JavaScript模式:将类属性“复制”到B类

时间:2013-02-12 16:28:25

标签: javascript class design-patterns prototype this

在一些大型项目中看到了这种JavaScript模式,它将ClassA的属性“复制”或“实现”到ClassB,但无法弄清楚使用“.call()”在ClassB的构造函数中调用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();

4 个答案:

答案 0 :(得分:2)

如果ClassA构造函数为空,那么这里没有什么大惊喜 - call ClassA的空构造函数绝对没有。

当您决定希望ClassA的构造函数非空时,您会看到该行现在具有非常重要的作用:构造ClassB对象也会调用{ {1}} - 新构造的ClassA对象上下文中的特定构造函数行为,如果ClassBClassB的逻辑“子类”,那么这是您所期望的。

(当然,JavaScript没有正确的“子类”,但这显然是尝试在语言中实现基于类的行为。)

答案 1 :(得分:1)

  

使用“.call()”在ClassB的构造函数中调用ClassA的空构造函数的目的

ClassA不为空时,让脚本仍然有效。当然,目前它什么都不做,但未来可能会有所改变。因此,最好实现完整的继承模式,以便以后更容易更改代码而不会引入错误。

一旦ClassA更改以实现自定义的特定于实例的属性(在构造函数中设置),您也希望将它们放在ClassB个实例上。因此,您在初始化期间也会在ClassA个实例上调用ClassB构造函数。

答案 2 :(得分:1)

如果ClassA构造函数为空(如示例代码中所示),那么是的,它什么都不做。

你看到这种模式的原因是它没有的时候。它类似于基于类的OO语言中的super调用。

如果你必须在ClassA构造函数中做一些工作来获得一个处于正确状态的对象,那么你很可能想要做同样的工作a&#34;子类&#34;。仅仅复制原型的属性可能还不够。

答案 3 :(得分:0)

使用.call,您可以将被调用方法中的this值更改为您指定的参数。 ClassA.call(this)使用ClassA作为上下文调用ClassB构造函数。这允许您在ClassB方法中使用ClassA的属性。这些方法都通过ClassB复制到ClassA.implementOn

您会注意到(new ClassA()).dance()什么都不做,但(new ClassB()).dance()提醒"dance"因为this.canDance是真的。

演示:http://jsfiddle.net/5v7xh/