V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
waiaan
V2EX  ›  JavaScript

问一个关于继承的问题

  •  
  •   waiaan · 2018-04-02 08:33:05 +08:00 · 3062 次点击
    这是一个创建于 2427 天前的主题,其中的信息可能已经有所发展或是发生改变。

    function extend(subClass,superClass){

    var F = function(){};
    
    F.prototype = superClass.prototype;
    
    subClass.prototype = new F();
    
    subClass.prototype.constructor = subClass;
    
    // 下面这段代码,为什么要赋值为 superClass.prototype ?可不可以直接赋值为 superClass ?二者有什么区别?
    
    subClass.superClass = superClass.prototype;
    
    // 
    
    if(superClass.prototype.constructor == Object.prototype.constructor){
    
    	superClass.prototype.constructor = superClass;
    
    }
    

    }

    谢谢。

    3 条回复    2018-04-02 15:02:11 +08:00
    WMutong
        1
    WMutong  
       2018-04-02 09:44:34 +08:00
    完整的继承:

    var SuperClass=function(){
    this.name='superClass';
    };
    SuperClass.prototype.sayName=function(){
    console.log('name: ' + this.name);
    };

    var SubClass=function(){
    SuperClass.call(this,name);
    };

    function extend(subClass,superClass){

    var F = function(){};

    F.prototype = superClass.prototype;

    subClass.prototype = new F(); //位置一

    subClass.prototype.constructor = subClass;

    // 下面这段代码,为什么要赋值为 superClass.prototype ?可不可以直接赋值为 superClass ?二者有什么区别?

    subClass.superClass = superClass.prototype; //位置二

    //

    if(superClass.prototype.constructor == Object.prototype.constructor){

    superClass.prototype.constructor = superClass;

    }
    }

    extend(SubClass,SuperClass);

    var sub1=new SubClass();
    console.log(sub1); //位置五
    sub1.sayName();

    例子中,位置五( sub1 实例)输出:

    SubClass{
    name:"superClass",
    __proto__:{
    constructor:function(){
    superClass:Object, //SuperClass 的构造函数
    ...
    prototype:SuperClass //SuperClass 的构造函数
    }
    }
    }

    如果没有“ subClass.superClass = superClass.prototype;”,那么 位置五 输出:

    SubClass{
    name:"superClass",
    __proto__:{
    constructor:function(){
    ...
    prototype:SuperClass //SuperClass 的构造函数
    }
    }
    }

    两者的区别在于:
    一个是在 SubClass 构造函数中添加了,等于 SuperClass 原型的 superClass 属性。
    一个没有添加。

    但不论 位置二 是否存在,SubClass 都已经在 位置一 继承了 SuperClass 的原型方法。
    所以,我认为 位置二 并不是必要的。


    同时《 JavaScript 高级程序设计 第三版》中对于 “寄生组合式继承” 使用的示例为:

    function inheritPrototype(subClass,superClass){

    var prototype=object(superClass.prototype);
    prototype.constructor=subClass;
    subClass.prototype=prototype;

    }
    waiaan
        2
    waiaan  
    OP
       2018-04-02 10:31:32 +08:00
    @WMutong
    不好意思,我没表述清楚,位置二并不是继承的一部分,只是在子类增加一个指向父类的属性,但是并不是直接指向父类的构造函数,而是指向父类的原型,所以我想问这两者有什么区别。
    谢谢。
    enginex
        3
    enginex  
       2018-04-02 15:02:11 +08:00
    subClass.superClass = superClass.prototype;// 位置二
    console.log(SubClass.superClass.sayName); //ƒ (){console.log('name: ' + this.name);}

    subClass.superClass = superClass ;//位置二
    console.log(SubClass.superClass.sayName); //undefined

    父类构造函数上并没有 sayName 方法,这里调用是通过原型链实现的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   992 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:45 · PVG 03:45 · LAX 11:45 · JFK 14:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.