简体   繁体   English

JavaScript - 动态原型模式+寄生组合继承

[英]JavaScript - Dynamic Prototype Pattern + Parasitic Combination Inheritance

I am working through Professional JavaScript for Web Developers, and have a question regarding Object Creation and Inheritance. 我正在为Web开发人员使用Professional JavaScript,并且有关于对象创建和继承的问题。 In the book, the Dynamic Prototype Pattern is discussed as a nice way of doing Combination Constructor/Prototype pattern while keeping the constructor and prototype encapsulated to the Object definition. 在本书中,动态原型模式被讨论为一种很好的组合构造函数/原型模式,同时保持构造函数和原型封装到Object定义。 Like this: 像这样:

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;

  if (typeof this.sayName != "function") {
    Person.prototype.sayName = function () {
      return this.name;
    };
  }
}

Of all the Object Creation patterns discussed in the book, I felt like this one looked the best. 在书中讨论的所有对象创建模式中,我觉得这个模型看起来最好。 Then when discussing inheritance, the book says Parasitic Combination Inheritance is considered the optimal inheritance paradigm. 然后在讨论继承时,书中说寄生组合继承被认为是最优的继承范式。 As follows: 如下:

function inheritPrototype(subType, superType) {
  var prototype = Object.create(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}

function SuperType(name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}

SuperType.prototype.sayName = function() {
  return this.name;
};

function SubType(name, age) {
  SuperType.call(this, name);
  this.age = age;
}

inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function() {
  return this.age;
}

As you can see, this code uses the Combination Constructor/Prototype Pattern for creating objects, where the prototypes are declared outside of the original object creation. 如您所见,此代码使用组合构造函数/原型模式来创建对象,其中原型在原始对象创建之外声明。 My question is, is there any issue with combining the Dynamic Prototype Pattern with Parasitic Combination Inheritance, like this: 我的问题是,将动态原型模式与寄生组合继承相结合是否存在任何问题,如下所示:

function inheritPrototype(subType, superType){
  var prototype = Object.create(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}

function SuperType(name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];

  if (typeof this.sayName != "function") {
    SuperType.prototype.sayName = function() {
        return this.name;
    };
  }
}

function SubType(name, age) {
  SuperType.call(this, name);
  this.age = age;

  if (typeof this.sayAge != "function") {
    SubType.prototype.sayAge = function() {
        return this.age;
    };
  }
}

inheritPrototype(SubType, SuperType);

I've tested this in a jsfiddle here and it seems to work fine, I just wanted to make sure there isn't something I'm missing that will cause problems later using this pattern/inheritance. 我在这里用jsfiddle进行了测试,它看起来工作正常,我只是想确保没有我遗漏的东西会在以后使用这种模式/继承时引起问题。

Also, as I know this book is a little older, are there new standards for object creation and inheritance? 另外,正如我所知,这本书有点旧,是否有对象创建和继承的新标准?

Both approaches seem broken . 两种方法似乎都被破坏

A given object prototype properties should be available even if the constructor function hasn't been called already. 即使尚未调用构造函数,也应该可以使用给定的对象原型属性。 In the other hand, it seems like this breaks the single responsibility principle , because the constructor is responsible of defining the prototype while it should just initialize the object being constructed . 另一方面,似乎这打破了单一责任原则 ,因为构造函数负责定义原型,而它应该只是初始化正在构造的对象

Just one question: how you would inherit a given object's prototype before the base object is ever constructed? 只有一个问题: 如何在构建基础对象之前继承给定对象的原型? :

var B = Object.create(A.prototype);

Wait! 等待! A.prototype won't contain expected properties unless some code calls new A() before! 除非某些代码之前调用了new A() ,否则A.prototype将不包含预期的属性!

// Ugly as hell!
new A();
var B = Object.create(A.prototype);

In summary, don't try to shortcut JavaScript: it's better to learn it and don't try to wrap inheritance with useless/pointless functions. 总之,不要尝试快捷方式JavaScript:最好学习它,不要试图用无用/无意义函数包装继承。

Actually, ECMA-Script 6 and above standards have already defined syntactic sugar to make JavaScript prototype chain look like classical inheritance: 实际上,ECMA-Script 6及以上标准已经定义了语法糖,使JavaScript原型链看起来像经典继承:

class B extends A 
{
}

...which is absolutely equivalent to: ......绝对相当于:

function B() {}
B.prototype = Object.create(A.prototype);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM