10

我有这个代码:

var MyClass = function(b) {
    this.a = b;
    this.getA = function() {
        return that.a;
    }
}

var SecondClass = function(b) {
    this.prototype = new MyClass(b);
    this.getB = function() {
        return 6;
    }
}

var a = new SecondClass(2);
console.log(a.getA());

输出告诉我 a 没有名为 getA() 的方法

我假设在 SecondClass 的构造函数中执行 this.prototype = new MyClass() 会导致它从 MyClass 继承方法?

我确信有更好的方法可以做到这一点,但我试图了解原型关键字的行为。

4

2 回答 2

15

prototype构造函数的特殊属性,而不是实例的。

当您使用 调用构造函数时new Func(),引擎将创建一个新对象,该对象继承自Func.prototypethis在构造函数内部设置以引用新对象。

因此,除了this.prototype作为普通属性之外,在分配发生时继承已经发生。

由于您没有为 分配任何方法MyClass.prototype,因此您不必在此处对原型继承做任何事情。您所要做的就是使用[MDN]MyClass应用到新创建的实例:.call

var SecondClass = function(b) {
    MyClass.call(this, b);
    this.getB = function() {
        return 6;
    }
};

但是,您应该将实例共享的所有方法添加到原型中,然后让每个实例都SecondClass继承它。完整的设置如下所示:

var MyClass = function(b) {
    this.a = b;
}
MyClass.prototype.getA = function() {
    return this.a;
};

var SecondClass = function(b) {
    // call parent constructor (like 'super()' in other languages)
    MyClass.call(this, b);
}
// Setup inheritance - add 'MyClass.prototype' to the prototype chain
SecondClass.prototype = Object.create(MyClass.prototype);
SecondClass.prototype.getB = function() {
    return 6;
};

var a = new SecondClass(2);
console.log(a.getA());

所有这些在 ES6 中都会变得更容易

于 2013-04-23T16:01:37.390 回答
4

一个名为“原型”的属性只对作为函数的对象感兴趣。在构造函数中为“原型”属性赋值无效(在这种情况下);重要的是构造函数本身的“原型”属性。

SecondClass.prototype = new MyClass();

或者其他的东西。构造函数的原型对象在所有构造的实例之间共享,因此使原型因构造函数参数而异也没有多大意义。

您可以做的另一件事是从“SecondClass”内部调用“MyClass”构造函数:

function SecondClass(b) {
  MyClass.call(this, b);
  this.getB = function() {
    return 6;
  };
}

这将具有使调用中this构造的 thatnew SecondClass()被“MyClass”构造函数修饰的效果。它不会真的是继承,但你会得到一个“getA”函数。

于 2013-04-23T15:57:40.747 回答