为什么使用.call vs直接将方法添加到原型?

时间:2014-03-20 22:31:22

标签: javascript node.js prototype

我正在使用的Node.js插件实现了一个我想更好理解的模式。

var Thing = function() {};

(function () {

    this.foo = function() {};
    this.bar = function() {}

}).call(Thing.prototype);

我知道call正在使用Thing.prototype上下文调用匿名函数。这是否意味着this.foo实际上被添加到Thing的原型中?如果有人可以解释的话,这对我来说有点模糊。

此外,与仅仅相反,这种方法的优点是什么:

Thing.prototype.foo = function() {};
Thing.prototype.bar = function() {};

2 个答案:

答案 0 :(得分:3)

在此代码中:

(function () {

    this.foo = function() {};
    this.bar = function() {}

}).call(Thing.prototype);

call(Thing.prototype)会导致匿名函数中this的值为Thing.prototype,因此它会在Thing.prototype上设置字段。请参阅call的文档,但基本上给call的第一个参数设置了被调用函数的this的值,然后剩下的参数是函数所采用的任何参数。因此,上面的代码会将字段foobar添加到Thing.prototype

如果您愿意,这种设置字段样式可以让您在闭包内容易地声明变量。例如:

(function () {

    var _foo = 0;

    this.foo = function() {
        return _foo;
    };

    this.bar = function() {
        _foo++;
    }

}).call(Thing.prototype);

_foo变量不能通过方法直接访问。

在很大程度上,人们喜欢什么样的风格。我更喜欢在问题中使用第二种风格:

Thing.prototype.foo = ...

这主要是因为我使用的一些工具可以更好地使用它。 (特别是jsdoc。)我更喜欢准备好访问我的对象的所有字段。

答案 1 :(得分:1)

OP中的模式与使用相同:

(function () {

    Thing.prototype.foo = function() {};
    Thing.prototype.bar = function() {}

})();

但这只有在封闭函数表达式创建有用的闭包时才会有用(根据Louis'回答)。

我认为调用版本的字符数少一些,因此可以更轻松地从 Thing.prototype 更改为 someOtherThing.prototype