Node.js: 无法从一个Javascript原型方法中调用另一个方法?

3
我想定义一个有两个公共方法的类。其中一个方法恰好可以用于实现另一个方法,但是我无论如何都不能让该函数在另一个函数的范围内被识别。我不知道这是否是特定于node.js的问题,但如果有关系的话,那么这是在node下运行的。
以下是一个简短的玩具问题,它复现了我所看到的行为:
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'
addSeveral()中如何调用addOne()
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]); };

不行。就像我说的,如果在方法名前加上 this.,它会出现另一个错误:TypeError: Object #<Object> has no method 'addOne' - Jason Black

1

您可以将this传递给forEach

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

或者您可以使用bind:

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

但是我会使用push.apply

addSeveral: function (arr) {
  [].push.apply(this.list, arr)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接