zoukankan      html  css  js  c++  java
  • 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}
  • 相关阅读:
    自己改了个{svn服务器端绿色版}
    Android去掉顶部的阴影
    SqliteOpenHelper的onUpgrade()死活不运行的解法
    前端模拟发送数据/调试的好工具:Chrome下的PostmanREST Client
    mouseenter & mouseleave VS mouseover & mouseout
    Android WindowManager$BadTokenException异常应对案例
    Eclipse快捷键大全(转载)
    360桌面JSAPI一个诡异的bug:客户端与网页通过js通信
    《你在哪》1.34强势发布,新增“图片墙”
    经过一个月的奋斗,我的第一个Android作品《麦芒》诞生了
  • 原文地址:https://www.cnblogs.com/miaodi/p/6879807.html
Copyright © 2011-2022 走看看