3

2つのパブリックメソッドでクラスを定義しようとしています。たまたま一方の方法がもう一方の方法を実装するのに役立つのですが、私の人生では、その機能をもう一方の範囲内で認識させることはできません。これが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'

どうすれば電話でき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

あなたはに渡すことができ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)
}
于 2012-12-04T21:29:47.843 に答える