繁体   English   中英

JavaScript模式:将ClassA属性“复制”到ClassB

[英]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对象,如果ClassBClassA的逻辑“子类”,那就是您所期望的。

(当然,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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM