3

我正在尝试使用两个公共方法定义一个类。碰巧其中一种方法对实现另一种方法很有用,但在我的一生中,我无法在另一种方法的范围内识别该功能。我不知道这是否特定于 node.js,但如果它很重要,它在 node.js 下运行。

这是一个简短的玩具问题,它重现了我所看到的行为:

function Foo() {
    this.list = [];
}

Foo.prototype = {
    addSeveral: function(arr) { arr.forEach(function(v) { addOne(v)} ) },
    addOne: function(item) { list.push(item); }
}

f = new Foo();
f.addSeveral([1,2,3]);

当我运行它时,它会爆炸:

[jasonb@localhost]$ node testobj.js

/home/jasonb/work/testobj.js:6
Foo.prototype.addSeveral = function(arr) { arr.forEach(function(v) { addOne(v)}
                                                                     ^
ReferenceError: addOne is not defined
    at /home/jasonb/work/entity_mapping/testobj.js:6:70

我已经尝试了所有我能找到的关于如何将东西分配给类的原型的变体,结果都是一样的。如果我尝试打电话this.addOne(v),它仍然会爆炸,但是TypeError: Object #<Object> has no method 'addOne'

我怎么能addOne()在里面打电话addSeveral()

4

2 回答 2

9

因为forEach为数组的每个元素调用一个回调函数,所以您正在丢失上下文(this不是Foo回调中的对象)。您可以关闭参考:

Foo.prototype = {
    addSeveral: function(arr) { var self=this; arr.forEach(function(v) { self.addOne(v)} ) },
    addOne: function(item) { this.list.push(item); }
}

...或者只是使用常规循环,这将具有更好的性能 - 函数调用很昂贵。

addSeveral: function(arr) { for(var i = 0; i < arr.length; i++) this.addOne(arr[i]); };
于 2012-12-04T21:03:00.720 回答
1

你可以传递thisforEach

addSeveral: function (arr) {
  arr.forEach(function (v) {
    this.addOne(v)
  }, this)
}

或者你可以使用绑定:

addSeveral: function (arr) {
  arr.forEach((function (v) {
    this.addOne(v)
  }).bind(this))
}

但我会做的是push.apply

addSeveral: function (arr) {
  [].push.apply(this.list, arr)
}
于 2012-12-04T21:29:47.843 回答