【问题标题】:Inherit construction logic, but run Super constructor on Sub object creation继承构造逻辑,但在创建 Sub 对象时运行 Super 构造函数
【发布时间】:2014-11-20 21:54:43
【问题描述】:

我用其他语言编写了一些东西,你继承了一个类,并且在创建子类的对象时调用超类构造函数。但是,在我发现的所有从 javascript 继承的模式中,超级构造函数实际上是在建立继承时运行的。

例子:

var thingy = function(){ this.constructionTime = new Date() };
var thing2 = function(){ this.type="thing2" };
thing2.prototype = new thingy();//thingy constructor actually runs here
var t2 = new thing2();//does NOT call thingy constructor
setTimeout(function(){
  var t3 = new thing2();
  t3.constructionTime == t2.constructionTime; // TRUE
},100);

然后我发现了一些不太常见的例子,他们做了这样的事情:

var athing = function(){
    this.constructionDate = new Date();
}
athing.prototype.showDate = function(){ console.log(this.constructionDate) };

var something = function(){
    athing.apply(this);
    this.note = "I'm something";
}
var x = new something();

然后调用 x = new something() 会运行构造函数,但不会继承方法。所以我加了

something.prototype = athing.prototype;

它不给 x 方法,而是新对象

y = new something();
y.showDate();//shows the date generated during its construction

确实有。

所以这是我可能过于宽泛的问题:我错过了什么吗?除了希望你的超级构造函数只运行一次之外,是否有理由不使用这种模式?

【问题讨论】:

  • 并不总是需要调用超级构造函数。
  • 好吧,我见过原型没有初始化任何变量等的代码,只是提供了一些方法,所以在这种情况下运行超级构造函数是不必要的,对吧?但是以我的代码为例,构造函数不仅做了一些事情,而且不仅仅是将变量初始化为固定值......
  • 通过将 Child 原型设置为 Parent 原型进行继承并不好。狗是动物,但动物并不总是狗。如给定的答案;最好使用 Object.create。以下答案可能对您有所帮助:stackoverflow.com/questions/16063394/…

标签: javascript inheritance


【解决方案1】:

当你想要子类化时,考虑使用

function Constructor() {
    SuperConstructor.apply(this);
    /* ... */
}
Constructor.prototype = Object.create(SuperConstructor.prototype);
Object.defineProperty(Constructor.prototype, 'constructor', {
    value: Constructor,
    configurable: true,
    writable: true
});
  • Constructor 内调用SuperConstructor 会使Constructor 实例在SuperConstructor 内设置属性。
  • Constructor.prototype 设置为Object.create(SuperConstructor.prototype) 会使Constructor 实例从SuperConstructor.prototype 继承属性。
  • 由于Constructor.prototype 已被替换,constructor 属性必须手动添加。使用defineProperty 使其不可枚举。

【讨论】:

  • 好吧,这看起来很酷,但为什么它比我的问题中的代码更好?第一部分 - SuperConstructor.apply - 与我的问题相同。我不太明白接下来的位...
  • @Aerik 是的,第一部分是一样的。但是您的 something 实例不会继承自 athing.prototype
  • “不继承自”具体是什么意思?当我设置“something.prototype = athing.prototype;”时,这不会创建继承吗?我的 y 对象有 showDate 方法...(不想争论,只是想了解您所说的细节)
  • @Aerik 啊,抱歉,我错过了那句话。那么是的,它们会继承,但这不是一种好的继承方式,因为这样你不能将属性添加到something,但不能添加到athing
【解决方案2】:

Javascript 是一种免费语言。尝试将继承和超级构造函数等经典概念硬塞进其中并不是一个好主意。

【讨论】:

  • 它可能是免费的,但“尝试......继承不是一个好主意”?见crockford.com/javascript/inheritance.html
  • 对不起,我的意思不是永远不要使用继承,我的意思是专门用超级构造函数概念继承。绝对应该使用原型继承!
猜你喜欢
  • 1970-01-01
  • 2013-06-01
  • 2023-04-03
  • 1970-01-01
  • 2012-01-31
  • 2016-03-24
相关资源
最近更新 更多