【问题标题】:Javascript Subclassing. Setting the constructor propertyJavascript 子类化。设置构造函数属性
【发布时间】:2016-07-05 22:53:48
【问题描述】:

多年来,我一直在编写/扩展我的课程:

function Container(name, contents, logErrors){
    this.name = name;
    this.contents = contents;
    this.logErrors = logErrors || false;
}

function Group(contents){
    this.id = new Date().getTime();
    Container.call(this, 'Group_'+ this.id, contents);
}
Group.prototype = Object.create(Container.prototype);
Group.constructor = Group; 

然而,在某些地方,我看到构造函数属性被分配在子类的原型上,而不是直接在子类上:

function Group(contents){
    this.id = new Date().getTime();
    Container.call(this, 'Group_'+ this.id, contents);
}
Group.prototype = Object.create(Container.prototype);
Group.prototype.constructor = Group; // <-----

哪个是正确的?

a) Group.prototype.constructor = Group;  
b) Group.constructor = Group;  
c) both a AND b  
d) neither a nor b  

如果可能,请引用您的来源

【问题讨论】:

  • class Group extends Container {}

标签: javascript oop prototype subclassing


【解决方案1】:

您应该始终使用 a) 原因如下。

function Container(){
    // code
}
function Group(){
    // code
}

此时请注意

console.log(Group.prototype.constructor === Group);
// true
console.log(Group.constructor === Function);
// true

如果你这样做了

Group.prototype = Object.create(Container.prototype);

你失去了原来的Group.prototype 并替换了它的所有方法。这意味着您也会丢失原来的Group.prototype.constructor

因此您可能会在此时观察到这一点。

console.log(Group.prototype.constructor === Container);
// true

现在,如果您想要复制方法之类的东西。

Group.prototype.copy = function() {  
    return new this.constructor(this.contents);
};

你最终可能会得到结果

var group1 = new Group();
console.log(group1.copy() instanceof Group);
// false

这可能不是预期的。

但如果你会这样做

Group.prototype.constructor = Group;

那么结果如预期的那样

console.log(group1.copy() instanceof Group);
// true

您也可以在这里阅读更多内容:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript#Inheritance

希望对您有所帮助。

【讨论】:

  • @Bergi,你关闭然后再次打开这个问题吗?
【解决方案2】:

只有 a) 是正确的。 point of the .constructor assignment 是您的子类的实例(即Group)继承了指向子类构造函数的.constructor 属性。他们确实从子类的原型对象(即Group.prototype)继承它,仅此而已。

如果您的代码都没有使用.constructor 属性,您也可以完全省略该语句。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多