2013-04-20 16 views
6

Her nesnenin erişime sahip olduğu, ancak her bir nesneye ayrı olarak eklenmesinin gerekmediği bir nesne dizisine işlev eklemeye çalışıyorum.Bir dizideki tüm nesneler arasındaki javascript işlevi paylaşımı

Size kısa bir örnek vereyim.

en her biri bir özelliği x ve bir özellik y sahip olan, bir dizi benzer nesneler içeren olduğunu varsayalım:

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

nesneler için herhangi bir x ve y toplamını hesaplamak istiyoruz.

İlk yaklaşım: belirli bir nesne için toplamını hesaplamak için

, bir çok gibi önceden belirlenmiş bir işlevi için bu nesneyi geçebileceği:

Bu oldukça çirkin ve tatmin edici
function xySum1(o) {return o.x + o.y;} 

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

, x ve y özelliklerine erişim farklı şekilde yapılır. Ayrıca, kodum farklı konumlardadır ve xySum1 işlevi, dizideki nesneler üzerinde hareket etmek için oluşturulduğu gibi kolayca tanınabilir değildir.

İkinci yaklaşım:

Bir olabilir dizi döngü ve her bir nesne için bir özellik olarak işlev eklemek:

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

Şimdi, toplam

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

çok daha iyi.

Sorunları

bu yaklaşımla, ancak, sorunlar vardır. I dizi daha sonra

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

bir yenisini eklerken işlev nesnesinin

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

Başka bir problem ilave edilmeden önce ilk olarak, toplam hesaplanamaz birçok nesne olması ve onlara eklenecek birçok işlev. Her bir işleve ayrı ayrı her bir nesneyi eklemek için iyi bir hafıza alanı kaybı gibi görünüyor.

Bunu daha verimli yapmanın bir yolu var mı?

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

Sonra yapabilirsiniz:

+6

'objects.xySum (0) 'nedir? – Bergi

+0

belki bir kurucu tanımlar, daha sonra işlevler prototipte olur mu? – user2264587

+0

Ayrıca şöyle bir Object.prototype yöntemi tanımlayabilirsiniz: Object.prototype.xySum = function() {return typeof this.x! == 'undefined' && typeof this.y! == 'undefined'? this.x + this.y: undefined;} '. – dfsq

cevap

8

bir sınıf tanımlayın

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

Bu yaklaşım: Alternatif

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 

, bu Bergi muhtemelen onun yorumunda söylemek istediğim şey biraz "kirli", ama aynı zamanda daha az bellek tüketiyor.

+1

Cevabınız için teşekkürler MaxArt. Nesnelerin dizisi zaten oluşturulduğunda bunu yapmak için bir yolu var mı? Programın kontrolümün ötesinde olan başka bir parçasından geçtiğini soruyorum. – ElRudi

+0

@ElRudi Bu durumda alternatifi kullanmayı öneririm: 'object' dizisinin işlevini tanımla ve bitti. Bunu, "seçenekler" in yapacağınız her kopyada veya bölümde yeniden tanımladığınıza dikkat edin. Ya da, her zaman "Nesneler" öğelerini kullanarak kendi nesnelerinizi oluşturabilirsin, yeni MyObject öğesinde olduğu gibi (nesneler [i] .x, nesneler [i] .y) ' – MaxArt

+0

Seçeneklerim: 1) bir sınıf tanımlayın, istenen özellikleri sınıfın her bir örneği için oluşturulacak dizideki tüm nesneleri kullanarak prototip -ve döngüsüne istenen işlevi ekleyin, (2) işlevi 'Nesne' prototipine ekleyin. bunun yerine, daha az kod satırının avantajıyla ve dizilerle daha az döngü yaparak, ya da (3) işlevi, kullanıldıkları dezavantaj ile bireysel nesnelerin yerine _array_'a ekleyebilen ya da kodlama pratiği yapamayan ya da olmayabilen sözdizimi diğer özelliklerden farklıdır ve nesne verileriyle birlikte kopyalanmaz. Doğru mu? – ElRudi

İlgili konular