2013-04-20 13 views
6

各オブジェクトがアクセスできるオブジェクトの配列に関数を追加しようとしていますが、各オブジェクトに個別に追加する必要はありません。配列内のすべてのオブジェクト間のjavascript関数の共有

私はあなたに簡単な例を教えてください。

は、各プロパティxとプロパティyを有するのは、私は同様のオブジェクトを含む配列を持っているとしましょう:

var objects = [{x:1, y:2}, 
       {x:0, y:5}, 
       {x:3, y:14} 
       ]; 

私はxとオブジェクトのいずれかのためyの合計を計算したいと思います。

最初のアプローチ:

所与のオブジェクトの和を計算するためにそうように、一方が予め定義された関数にこのオブジェクトを渡すことができ:

function xySum1(o) {return o.x + o.y;} 

objects[0].x  //--> returns 1 
objects[0].y  //--> returns 2 
xySum1(objects[0]) //--> returns 3 

これは非常に醜いと不満足なものです、 xyのプロパティへのアクセスが異なるように行われます。また、私のコードは異なる場所にあり、関数xySum1は、配列内のオブジェクトに作用するように作成されていると容易には認識できません。

第二のアプローチ:

一可能性配列をループし、各オブジェクトにプロパティとしての機能を追加します。

for (var i=0; i < objects.length; i++) { 
    objects[i].xySum2 = function() {return this.x + this.y;}; 
} 

ここで、和は

objects[0].x  //--> returns 1 
objects[0].y  //--> returns 2 
objects[0].xySum2() //--> returns 3 
により得られます

これははるかに優れています。

問題

このアプローチの問題は、しかし、があります。私は、アレイ

objects.push({x:5,y:21}); 

を新しい要素を追加するときに、関数はオブジェクト

objects[3].xySum2() //-->TypeError 

に追加される前にまず、その合計が計算できないもう一つの問題は、私は多くのオブジェクトを持っているということで、それらに追加する多くの機能。それぞれのオブジェクトに個々のオブジェクトを個別に追加するのは、良いメモリ空間を無駄にしているようです。

これをより効率的に行う方法はありますか?

+6

'objects.xySum(0)'についてはどうですか? – Bergi

+0

はおそらくコンストラクタを定義すると、関数はプロトタイプに入りますか? – user2264587

+0

また、Object.prototypeメソッドを以下のように定義することもできます: 'Object.prototype.xySum = function(){return typeof this.x!== '未定義' && this.y!== 'undefined'? this.x + this.y:undefined;} '。 – dfsq

答えて

8

クラスを定義します。

function MyObject(x, y) { 
    this.x = x; 
    this.y = y; 
} 
MyObject.prototype = { 
    xySum2: function() { 
     return this.x + this.y; 
    }, x: 0, y: 0 
}; 

次に、あなたが行うことができます:

また
var objects = [ 
    new MyObject(1, 2), 
    new MyObject(0, 5), 
    new MyObject(3, 14) 
]; 
objects[0].xySum2(); // 3 

objects.push(new MyObject(5, 21)); 
objects[3].xySum2(); // 26 

、これはBergiは、おそらく彼のコメントで言いたかったものです:

objects.xySum = function(index) { 
    return this[index].x + this[index].y; 
}; 

このアプローチ少し汚れているだけでなく、メモリ消費も少なくなります。

+1

あなたの答えはMaxArtに感謝します。オブジェクトの配列が既に作成されたら、これを行う方法はありますか?私はそれが私のコントロールを超えているプログラムの別の部分から渡されたので尋ねます。 – ElRudi

+0

@ElRudiその場合は、代わりに 'objects'配列の関数を定義することをお勧めします。あなたが 'options'を作るつもりのすべてのコピーや部分でそれを再定義することに留意してください。そうでなければ、 'new MyObject(objects [i] .x、objects [i] .y)'のように、 'objects'の要素を使って自分の配列を作成することができます。 – MaxArt

+0

1)クラスを定義し、必要な関数をそのプロトタイプに追加し、得られた配列内のすべてのオブジェクトをループして、同じプロパティを持つクラスのインスタンスごとに作成する、(2)関数をObjectのプロトタイプに追加する代わりにコードの行数が少なくて配列のループが少ないというメリットがあり、(3)個々のオブジェクトの代わりに_array_に関数を追加すると、それが使用されるという欠点があります他のプロパティとは構文的に異なり、オブジェクトデータとともにコピーされません。 正しいですか? – ElRudi

関連する問題