我正在尝试使用两个公共方法定义一个类。碰巧其中一种方法对于实现另一种方法很有用,但对于我的生活,我无法在另一种方法的范围内识别该功能。我不知道这是否是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()
?
答案 0 :(得分: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]); };
答案 1 :(得分: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)
}