不创建 parent object 的原型继承

Prototypical inheritance without creating a parent object

所以我在读 Head First Javascript Programming 这本书遗产。

这本书告诉我,要实现多重继承,您应该将构造函数的原型设置为 parent 的新 object。

举个例子:

    //Parent
    function Dog (name){
       this.name = name; 
    };



   //Child
   function AwesomeDog(name){
      Dog.call(this, name);
   };
   AwesomeDog.prototype = new Dog();
   AwesomeDog.prototype.constructor = AwesomeDog;
   AwesomeDog.prototype.isAwesome = true;

现在我不同意这是最好的方法,你只为它的原型 属性 调用 Dog 构造函数,但你也得到了它的名字 属性,你通常永远不会使用,因此总是未定义的。

为什么不这样做:

 AwesomeDog.prototype = Dog.prototype;

反正你只对原型感兴趣,为什么不呢?

我认为这更好,原因有两个:

  1. 创建一个新的 object 的开销被忽略了(微不足道,但它是一些东西)
  2. 您的 child 原型中没有无用的属性,它们可能始终未定义。

现在这本书在各个方面都非常出色,让我相信我可能错过了一些关键的东西,但我看不到什么。我无法想象具有双重属性(child object 中的一个和原型中的未定义版本)的任何用例都是有用的。

我的思路对不对,我能坚持我的方法吗?

JavaScript中的对象继承也是构造函数继承的基础。 每个函数都有一个可以修改或替换的原型 属性。该原型 属性 被自动分配为一个新的通用对象,该对象继承自 Object.prototype 并具有一个自己的 属性 调用构造函数。实际上,JavaScript 引擎会为您执行以下操作:

// you write this
function YourConstructor() {
    // initialization
}

// JavaScript engine does this for you behind the scenes
YourConstructor.prototype = Object.create(Object.prototype, {
    constructor: {
        configurable: true,
        enumerable: true,
        value: YourConstructor
        writable: true
    }
});

所以没有做任何额外的事情,这段代码设置了构造函数的 原型 属性 到继承自 Object.prototype 的对象, 这意味着 YourConstructor 的任何实例也继承自 Object 。原型。 YourConstructor 是 Object 的 子类型 ,并且 Object 是超类型 共 YourConstructor.

Now I don't agree that this is the best way to do it, you call the Dog constructor only for its prototype property, but you also get the name property with it, that you will typically never use and therefore always be undefined.

你完全正确。使用 new 有这些问题,因此不鼓励。

Why not just do this:

AwesomeDog.prototype = Dog.prototype;

这有一个问题:AwesomeDogDog 实例共享同一个原型。因此,它们将继承相同的属性和方法,因此子类化没有意义。 constructor 应该是 AwesomeDog 还是 Dog

相反,正确的方法是将 AwesomeDog.prototype 分配给继承自 Dog.prototype 的对象,但不调用 Dog。您可以使用 Object.create:

AwesomeDog.prototype = Object.create(Dog.prototype);
AwesomeDog.prototype.constructor = AwesomeDog;