• JS实现OO机制


    一、简单原型机制介绍

    继承是OO语言的标配,基本所有的语言都有继承的功能,使用继承方便对象的一些属性和方法的共享,Javascript也从其他OO语言上借鉴了这种思想,当一个函数通过"new"创建出一个实例后,那么这个实例就拥有这个函数的prototype对象所有的属性和方法,从而实现所有的实例都能共享一组实例和方法,Javascript所谓的类就行通过修改这个prototype对象实现的,以区别其他的原生对象,及自定义类

    <script>
        function A(){}
        A.prototype={
            a:"a",
            fun:function () {}
        }
        var a=new A();
        var b=new A();
        alert(a.a===b.a);//true
        alert(a.fun===b.fun)//true
    </script>

    总结:

    1、我们将定义在原型上的方法(属性)叫做原型方法,原型方法(属性)被所有的实例所共享

    2、但是我们不能加所有的属性和方法都定义到原型上,JS为了实现差异化,允许我们将方法和属性定义到构造函数内部,这叫做特权方法(属性)。

    3、因此我们把共享的属性和方法放到原型内,把私有的数据放到构造函数里面。

        function A() {
            var count=0;
            this.a=1;
            this.fun=function () {
                
            }
        }
        A.prototype={
            b:1,
            fun1:function () {}
        }
        var a=new A();
        var b=new A();
        alert(a.a);//输出1
        alert(a.count);//输出undefined

    4、当我们把方法和属性定义于this上面,那么外界还是能访问到,所以当方法(属性)是特有属性(方法),那么别置于this之下,之间定义到构造函数内部,并用var修饰,这是它就是名副其实的私有属性。

        function A(){
            var count=1;
            this.a=666;
            this.fun=function () {
                
            }
        }
        A.prototype={
            a:"aaa",
            b:666666,
            fun:function () {
            }
        }
        var a=new A();
        var b=new A();
        alert(a.a===b.a);//输出:true  因为a是基本类型所以比较值
        alert(a.fun===b.fun);//输出:false  比较引用
        alert(a.a);//输出:666  说明特权属性会覆盖原型属性,当两个属性名一样的时候
        delete a.a;
        alert(a.a);//输出:aaa   删除特权属性后,输出原型属性

    5、特权方法(属性)只是遮住原型方法(属性),只要使用delete 删除,就又能访问到原型属性

    二、OO静态方法实现

    <script>
        function A(){}
        A.a=function () {
            alert(1);
        }
        A.a();//输出:1;
    </script>

    三、OO继承的实现

    上面介绍了原型模式的用法,我们给prototype定义了什么方法和属性,那么对应的实例就会共享prototype中的方法和属性,那么当我们将A对象的prototype属性赋给B对象时,那么B对象就拥有了所有的A对象中原型中的属性和方法。

        function A(){}
        A.prototype={
            a:666
        }
        function B(){}
        B.prototype=A.prototype;
        var b=new B();
        alert(b.a);//输出:666

    由于引用着同一个对象,这意味着,我们修改A对象的原型,那么B对象的原型也会受到影响,因此我们不能把同一个对象赋给两个类,所以这个问题需要解决

    方法一:通过for in把父类的原型属性和方法一一的赋给子类的原型

        //通过继承拷贝来实现继承,缺点是无法通过instanceof来判断实例类型
        function extend(destination,source){
            for(var prototype in source){
                destination[prototype]=source[prototype];
            }
            return destination;
        }
    
        function A(){}
        A.prototype={
            a:666
        }
        function B(){}
        var b=extend(A,new A());
        alert(b.a);//输出:666

    方法二:子类的原型不从父类的原型那里直接获得,而是通过一个中间函数,将父类的原型赋值给该函数,然后这个函数的实例作为子类的原型

        /**
         * 解决通过prototype赋值型继承的应用同一个对象的问题
         * @constructor
         */
    
        //通过中间函数来解决
        function A(){}
        A.prototype={
            a:666
        }
        function Bridge(){}
        Bridge.prototype=A.prototype;
    
        function B(){}
        B.prototype=new Bridge();
    
        var a=new A();
        var b=new B();
        alert(A.prototype==B.prototype);//说明他们的原型被分开
        alert(a.a===b.a);//输出:true  子类共享父类的原型属性(方法)
        //为父类动态添加方法
        A.prototype.lala=function(){
            alert(1);
        }
        b.lala();//输出:1  子类获得了这个方法
    
        B.prototype.lele=function () {
            alert(2);
        }
        //a.lele();//error  父类不具有子类的方法
    
        alert(b instanceof A);//true
        alert(b instanceof B);//true

    方法二:能通过instanceof的验证,现在es5就自带了这种方法来实现原型继承。这种方法还有另外一种简介的实现Object.Creat

    <script>
        /**
         * 继承2的简洁版,通过一个方法来实现继承
         * @param o  父类的原型
         * @returns {F}  中间函数的原型
         */
        Object.create=function (o) {
            function F() {}
            F.prototype=o;
            return new F();
        }
    </script>
  • 相关阅读:
    编程命名规范化
    傻孩子菜单框架(转)
    《数据结构》示范程序树的长子-兄弟表示法
    keil中编译时出现*** ERROR L107: ADDRESS SPACE OVERFLOW
    单片机C语言下LCD多级菜单的一种实现方法
    指针函数与函数指针的区别
    LCD1602汉字、自定义字符取模
    FFmpeg纯净版解码 av_parser_parse2
    ffmpeg 内存读写相关
    AudioSpecificConfig
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/6515907.html
Copyright © 2020-2023  润新知