• JavaScript的几种(原型)继承


    定义Foo,Bar

    其中,Bar继承Foo

    a是Bar的实例,包含有Foo和Bar的函数和属性:

    function Foo(name) {
        this.name = name;
    }
    
    Foo.prototype.myName = function() {
        return this.name;
    };
    
    function Bar(name,label) {
        Foo.call( this, name );
        this.label = label;
    }
    
    // here, we make a new `Bar.prototype`
    // linked to `Foo.prototype`
    Bar.prototype = Object.create( Foo.prototype ); //核心代码
    
    // Beware! Now `Bar.prototype.constructor` is gone,
    // and might need to be manually "fixed" if you're
    // in the habit of relying on such properties!
    
    Bar.prototype.myLabel = function() {
        return this.label;
    };
    
    var a = new Bar( "a", "obj a" );
    
    a.myName(); // "a"
    a.myLabel(); // "obj a"

    其中核心代码为

    Bar.prototype = Object.create( Foo.prototype );

    我们把这行代码换为以下几种写法,仍可使输出不变,但内部实现则完全不同了。

    1、Bar.prototype = Foo.prototype;

    推荐指数:★

    评价:执行Bar.prototype.myLabel = ...的赋值语句会直接修改Foo.prototype对象本身,还不如不要Bar只用Foo

    //第1种
    Bar.prototype = Foo.prototype;
    
    a; //输出如下
    Bar {name: "a", label: "obj a"}
    
    a.__proto__; //输出如下
    Object {myName: function, myLabel: function, constructor: function}
    
    a.__proto__.__proto__; //输出如下
    Object {method: function, __defineGetter__: function, __defineSetter__: function, hasOwnProperty: function, __lookupGetter__: function…}

    2、Bar.prototype = new Foo();

    推荐指数:★

    评价:Foo函数的内容有可能产生副作用,他的操作将直接影响Bar()的后代,后果不堪设想。如下面的undefined

    //第2种
    Bar.prototype = new Foo();
    
    a; //输出如下
    Bar {name: "a", label: "obj a"}
    
    a.__proto__; //输出如下
    Foo {name: undefined, myLabel: function}
    
    a.__proto__.__proto__; //输出如下
    Object {myName: function, constructor: function}

    3、Object.setPrototypeOf(Bar.prototype,Foo.prototype);

    推荐指数:★★★★★

    评价:完美,Bar的构造函数没变

    Bar.prototype.constructor
    function Bar(name,label) {
    Foo.call( this, name );
    this.label = label;
    }

    //第3种
    Object.setPrototypeOf(Bar.prototype,Foo.prototype);
    
    a; //输出如下
    Bar {name: "a", label: "obj a"}
    
    a.__proto__; //输出如下
    Foo {myLabel: function, constructor: function}
    
    a.__proto__.__proto__; //输出如下
    Object {myName: function, constructor: function}

    4、Bar.prototype = Object.create(Foo.prototype);

    推荐指数:★★★★

    评价: Bar.prototype本身的constructor丢失了,去原型找,导致

    Bar.prototype.constructor
    function Foo(name) {
    this.name = name;
    }

    //原文
    Bar.prototype = Object.create(Foo.prototype);
    
    a; //输出如下
    Bar {name: "a", label: "obj a"}
    
    a.__proto__; //输出如下
    Foo {myLabel: function}
    
    a.__proto__.__proto__; //输出如下
    Object {myName: function, constructor: function}
  • 相关阅读:
    java1.8版本的HashMap源码剖析
    java并发包——阻塞队列BlockingQueue及源码分析
    java多线程(二)-线程的生命周期及线程间通信
    单例设计模式的回顾。。。。
    java多线程的(一)-之java线程的使用
    根据IO流源码深入理解装饰设计模式使用
    IO流回顾与总结第一篇之字节流与字符流的操作。。。。。
    java中的异常类型以及区别????
    设计模式之装饰设计案例
    集合源码(一)之hashMap、ArrayList
  • 原文地址:https://www.cnblogs.com/miaodi/p/6879807.html
Copyright © 2020-2023  润新知