![](/img/trans.png)
[英]How to instantiate a class(ClassA) inside another class(ClassB) and use the ClassA object as a property in ClassB in JavaScript?
[英]JavaScript pattern: “copy” ClassA properties to ClassB
在一些大型项目中看到了这种JavaScript模式,它将ClassA的属性“复制”或“实现”到ClassB,但无法弄清楚在传递ClassB的构造函数中使用“.call()”调用ClassA的空构造函数的目的是什么ClassB实例为“this”绑定?
var ClassA = function() {
//this function is totally empty
};
ClassA.prototype = {
jump: function() {...some code...},
dance: function() {
if (this.canDance) {
alert("dance");
}
}
};
ClassA.implementOn = function(targetClassOrObject) {
for ( var prop in ClassA.prototype ) {
targetClassOrObject[ prop ] = ClassA.prototype[ prop ];
}
};
var ClassB = function() {
this.canDance = true;
ClassA.call(this); // <------------What's the purpose of this line?
};
ClassA.implementOn(ClassB.prototype);
var instanceOfB = new ClassB();
instanceOfB.dance();
如果ClassA
构造函数为空,那么这里没有什么大惊喜 - call
ClassA
的空构造函数绝对没有任何意义。
但是,当您决定要使ClassA
的构造函数为非空时,您会看到该行现在具有非常重要的作用:构造ClassB
对象也会在新构造的上下文中调用ClassA
特定的构造函数行为。 ClassB
对象,如果ClassB
是ClassA
的逻辑“子类”,那就是您所期望的。
(当然,JavaScript没有合适的“子类”,但这显然是尝试在语言中实现基于类的行为。)
使用“.call()”在ClassB的构造函数中调用ClassA的空构造函数的目的
当ClassA
不为空时让脚本仍然有效。 当然,目前它什么都不做,但未来可能会有所改变。 因此,优良作法是实现完整的继承模式,以便以后更容易更改代码而不会引入错误。
一旦ClassA
更改为实现自定义的特定于实例的属性(在构造函数中设置),您也希望它们也在ClassB
实例上。 因此,您在初始化期间也会调用ClassB
实例上的ClassA
构造函数。
如果ClassA
构造函数为空(如在您的示例代码中),那么是的,它什么都不做。
你看到这种模式的原因,是因为它不是。 它类似于基于类的OO语言中的super
调用。
如果你必须在ClassA
构造函数中做一些工作来获得一个处于正确状态的对象,那么你很可能想要在“子类”中做同样的工作。 仅仅复制原型的属性可能还不够。
使用.call
,您可以将被调用方法中的this
值更改为您指定的参数。 ClassA.call(this)
使用ClassB
作为上下文调用ClassA
构造函数。 这允许您在ClassA
方法中使用ClassB
的属性。 这些方法都通过ClassA.implementOn
复制到ClassB
。
你会注意到(new ClassA()).dance()
什么都不做,但是(new ClassB()).dance()
提醒"dance"
因为this.canDance
是真的。
演示: http : //jsfiddle.net/5v7xh/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.