我想知道是否可以通过自动使用超类的构造函数在javascript中实例化子类。
考虑一下(灵感来自this other question here on SO):
function A(prop) {
this.prop = prop;
}
A.prototype.whatAmI = function() {
console.log(
"I'm an instance of %s, my prop is %s",
this instanceof A1? "A1" : "A2",
this.prop
);
};
function A1() {
A.apply(this, arguments);
}
A1.prototype = new A();
A1.prototype.constructor = A1;
function A2() {
A.apply(this, arguments);
}
A2.prototype = new A();
A2.prototype.constructor = A2;
var a1 = new A1("foo").whatAmI(); //I'm an instance of A1, my prop is foo
var a2 = new A2("bar").whatAmI(); //I'm an instance of A2, my prop is bar
但是,参考this article,在第一个例子中,我遇到了这行代码:
Cat.prototype.constructor = Cat;
//Otherwise instances of Cat would have a constructor of Mammal
我认为这正是我所需要的:A1
和A2
的实例具有A
的构造函数。很遗憾,评论A1.prototype.constructor = A1
并清空A1
的正文(同样适用于A2
)不起作用:
function A1() {}
A1.prototype = new A();
function A2() {}
A2.prototype = new A();
var a1 = new A1("foo").whatAmI(); //I'm an instance of A1, my prop is undefined
var a2 = new A2("bar").whatAmI(); //I'm an instance of A2, my prop is undefined
最后,将A
的构造函数更改为使用arguments
对象而不是显式传递prop
也不会产生任何影响:
function A() {
this.prop = arguments[0];
}
甚至可以通过prototype
属性稍微摆弄来实现我想要的目标吗?
答案 0 :(得分:4)
Cat.prototype.constructor = Cat; //Otherwise instances of Cat would have a constructor of Mammal
我认为这正是我所需要的:A1和A2的实例 有A的构造函数。
不,那不是他们的意思。 A1
和A2
函数 仍然是他们自己被调用的构造函数,你无法改变它。
本文描述的问题是,当您覆盖.constructor
时,所有实例都继承以指出其构造函数的AX.prototype
属性不再有效。另请参阅What is the `constructor` property really used for?(及相关问题)。
不幸的是评论
A1.prototype.constructor = A1
和 清空A1的身体(同样适用于A2)不起作用。
通过清空身体,它不再做任何事情了。你仍然需要明确地致电A
,你不会解决这个问题。您可以做的是创建一个通用工厂,为A
创建不做任何特殊操作的子类,但我认为它不值得。
哦,不要忘记:You should not use new
for creating prototypes!
subclass(parent) {
function Child() {
parent.apply(this, arguments);
}
Child.prototype = Object.create(parent.prototype);
Child.prototype.constructor = Child;
return Child;
}
function A(prop) {
this.prop = prop;
}
A.prototype.whatAmI = function() {
console.log(
"I'm an instance of %s, my prop is %s",
this instanceof A1? "A1" : "A2",
this.prop
);
};
var A1 = subclass(A),
A2 = subclass(A);