2011-06-20 26 views
7

ı bir JavaScript nesnesi var diyelim ben .length değil bir işlev yapmaya çalışıyorduSeti length özelliği

var x = new a(); 
x.add(3); 
x.add(4); 
alert(x.length()); // 2 
alert(x.remove()); // 4 
alert(x.length()); // 1 

, bu yüzden Bu gibi erişebilir: x.length, ama bunu işe almak için şansım yoktu.

Bunu denedim, ancak o zaman A uzunluğu çünkü o, 0 verir: Ben de bu çalıştı

function a(){ 
    var A = []; 
    this.length = A.length; 
    //rest of the function... 
}; 

ve aynı zamanda 0 verir:

function a(){ 
    var A = []; 
    this.length = function(){ 
     return A.length; 
    }(); 
    //rest of the function... 
}; 

yapmak nasıl Nesnedeki dizinin doğru uzunluğunu çıkarmak için x.length'u alıyorum? 'özel' kalmak A istiyorsanız

+1

İşte (http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/) [Array alt sınıfı teşebbüs] ilgili bazı ilginç okuma bu. – Pointy

cevap

2

. Çıkışı geri döndürmek için, aslında işlevi çağırmak zorundasınız, yani: a.length(). Eğer length özelliği bir işlev ancak gerçek değer olmasını istemiyorsanız bir kenara

, sen mülkü dönmek için nesneyi değiştirmeye gerekecektir.

this.length = { 
    'valueOf': function(){ 
     return A.length; 
    }, 
    'toString': function(){ 
     return A.length; 
    } 
}; 

Şimdi x.length olarak uzunluğunu erişebilirsiniz:

function a() { 
    var A = []; 
    this.length = 0; 
    this.add = function(x) { 
    A.push(x); 
    this.length = A.length; 
    }; 
    this.remove = function() { 
    var removed = A.pop(); 
    this.length = A.length; 
    return removed; 
    }; 
}; 
+0

Geçerli bir yanıttır, ancak .remove() yönteminin dönüş değerini değiştirmiş olmanız dışında (cevabınızdaki herhangi bir tasarım hatası ile değil). – JAAulde

+0

@JAAulde Teşekkür ederim, kendi yazımı yaparken ekledim. Rocket'in orijinal sorusuna benzer şekilde güncellendi. – scurker

3

, size sorulduğunda kontrol eden bir yöntem gerekmez, böylece A 'ın uzunluğu değiştiren her operasyonda kamu length özelliğini güncellemeniz gerekir. Bunu 'özel' yöntemle yapardım.

Kodu:

var a = function(){ 
    var instance, A, updateLength; 

    instance = this; 
    A = []; 
    this.length = 0; 

    updateLength = function() 
    { 
     instance.length = A.length; 
    } 

    this.add = function(x){ 
     A.push(x); 
     updateLength(); 
    }; 

    this.remove = function(){ 
     var popped = A.pop(); 
     updateLength(); 

     return popped; 
    }; 
}; 

Demo: Ben knoledge bir değişken bir yöntemin değerini döndüremez gibi bir değişken olarak erişebilirsiniz sanmıyorum http://jsfiddle.net/JAAulde/VT4bb/

0

Eğer dizi nesnesini ele geçiremezseniz ve push/pop yöntemleri çağrıldığında (çirkin!) değişkeninizin güncellemesinde hack yapmaya başlamazsanız. senin yöntem versiyonu çalışması için ben aşağıdakileri yapmanız gerektiğini düşünüyorum: Eğer a.length çağırdığınızda, bir işlev dönen Çünkü

function a(){ 
    this.A = []; 
    this.length = function(){ 
     return this.A.length; 
    }; 
    this.add = function(x){ 
     this.A.push(x); 
    }; 
    this.remove = function(){ 
     return this.A.pop(); 
    }; 
}; 
+0

Geçerli, 'method', sürümü iyi çalışıyor. '' '' '' '' '' '' '' '' ''' '' '' '' '' '' Önünde yoktu, çünkü bu onu işlevin 'özel' bir üyesi yapar. –

+0

ah, benim kötü. Var'ı özledim. Bana bildirdiğiniz için teşekkürler. – joostschouten

5

Sen valueOf hack kullanabilirsiniz. (Belki de sadece ben varım, ama bana göre, bu yöntemle ilgili bir şey çok döner kavşak hissediyor, ve daha sağlam bir çözümle gitmek için yeterince kolay ve örneğin her bir değişiklikten sonra uzunluk özelliğini günceller.)

+0

benden daha hızlı ve en iyi cevap ... + 1! –

+0

Bunu yapmanın oldukça zor bir yolu. Bunu sevdim. –

1

Herkesin söylediği şey ES3 hakkında doğru olsa da, bu uzunluk bir işlev olmalıdır (aksi takdirde aksi durumda kesilmedikçe değeri sabit kalacaktır), ES5'te istediğinizi elde edebilirsiniz (bunu deneyin).) örneğin krom: Ben senin orijinal öyle görünen bir fonksiyonu olarak bıraktım rağmen muhtemelen yerine fonksiyon a Object.create kullanmalıdır

function a(){ 
    var A = [], 
     newA = { 
     get length(){ return A.length;} 
     }; 
    newA.add = function(x){ 
     A.push(x); 
    }; 
    newA.remove = function(){ 
     return A.pop(); 
    }; 
    return newA; 
} 

var x = a(); 
x.add(3); 
x.add(4); 
alert(x.length); // 2 
alert(x.remove()); // 4 
alert(x.length); // 1 

.

+0

Cool, bu çalışma (Chrome 13'te). Uzunluk() 'sözdizimi hakkında bilmiyordum. –

+1

Çok sayıda tarayıcıda çalışır: Chrome 12, FF4. Henüz IE'de henüz uygulanmadı. – davin

-1
function a(){ 
    this.A = []; 
    this.length = function(){ 
     return this.A.length; 
    }; 
    this.add = function(x){ 
     this.A.push(x); 
    }; 
    this.remove = function(){ 
     return this.A.pop(); 
    }; 
}; 
+0

Teşekkürler, ama bu soru çözüldü. –