5

Başka bir nesnenin yapıcısının "bu" atamalarını kullanması ve tüm bu nesnelerin prototipini alması için bir JavaScript nesnesi almaya çalışıyorum fonksiyonlar. İşte başarmak çalışılıyor ne bir örnek:"this =" işlevini kullanarak Javascript işlevi "atamada geçersiz sol taraf" verir

/* The base - contains assignments to 'this', and prototype functions 
    */ 
function ObjX(a,b) { 
    this.$a = a; 
    this.$b = b; 
} 

ObjX.prototype.getB() { 
    return this.$b; 
} 

function ObjY(a,b,c) { 
    // here's what I'm thinking should work: 
    this = ObjX(a, b * 12); 
    /* and by 'work' I mean ObjY should have the following properties: 
    * ObjY.$a == a, ObjY.$b == b * 12, 
    * and ObjY.getB == ObjX.prototype.getB 
    * ... unfortunately I get the error: 
    *  Uncaught ReferenceError: Invalid left-hand side in assignment 
    */ 

    this.$c = c; // just to further distinguish ObjY from ObjX. 
} 

Ben ObjY 'bu' için ObjX en atamaları subsume olması konusunda Düşüncelerin için minnettar olurum (yani tüm this.$* = * atamaları tekrarlamak zorunda değildir ObjY'nin kurucusu) ve ObjY ObjX.prototype olduğunu varsayalım. İdeal

function ObjY(a,b,c) { 
    this.prototype = new ObjX(a,b*12); 
} 

ben yani gibilerin 'klasik' cepten ikame herhangi birini kullanmak zorunda değildir (bir prototypal şekilde bunu öğrenmek istiyorum:

ilk düşüncem şu denemektir Base2).

Terminoloji doğruysa, ObjY'nin anonim (örn. factory['ObjX'] = function(a,b,c) { this = ObjX(a,b*12); ... }) olması dikkat çekicidir.

Teşekkür ederiz.

+1

related: [? Ben yeni bir değer atanamıyor Neden “Bu” bir prototip fonksiyonunda] (http: // stackoverflow.com/q/9713323/1048572) – Bergi

cevap

15

Bunu yapamazsınız, çünkü this değeri tanıma göre immutable, bu şekilde başvuruda bulunamazsınız.

bir çözüm ObjY arasında this nesnesi içinde ObjX yapıcı işlevi çalıştırmak için call veya apply yöntemleri kullanmak olacaktır:

Yukarıdaki örnekte
function ObjY(a,b,c) { 
    ObjX.call(this, a, b * 12); 
    this.$c = c; 
} 

, ObjX fonksiyon yürütülür onun this değerini değiştirerek, Bu nedenle, bu nesnede bu nesneye yaptığınız tüm özellik uzantıları, this değerinin ObjY yapıcısında ifade ettiği yeni nesneye yansıtılacaktır.

call yöntemi biter bitmez, this nesnesi artar ve $c değerinizi eklemek gibi daha fazla özellik uzantısı oluşturabilirsiniz.

Düzenleme: prototype özellik sadece başka özelliği olarak olacak tutumlarını nesne için özel bir anlamı vardır, çünkü prototip Hakkında, örnek, işe yaramaz, bu yapıcı işlevleri kullanılmalıdır.

Yapımcıların prototype özelliğini, tüm nesnelerin sahip olduğu dahili [[Prototype]] özelliğiyle karıştırıyor olabileceğini düşünüyorum.

Mozilla gibi bazı uygulamaları, sen obj.__proto__; üzerinden erişebilecek rağmen, bu özellik (değiştirilemez

[[Prototype]] özellik yalnızca ([[Construct]] dahili operasyon aracılığıyla) new operatör tarafından ayarlanabilir ve içinde ECMAScript 5, Object.getPrototypeOf yöntemi tanıtıldı, ancak doğrudan bununla uğraşmanızı tavsiye etmem).senin yapıcı işlevi çalıştırıldığında

Aslında, this değeri ifade eder o nesnenin iç [[Prototype]] mülkiyet, zaten şantiye prototype özelliğine ayarlandı. Gördüğünüz gibi, sizin ObjY devralır da özellikleri ObjX.prototype eklenen yapacak

function ObjY(a,b,c) { 
    ObjX.call(this, a, b * 12); 
    this.$c = c; 
} 

ObjY.prototype = new ObjX(); 
ObjY.prototype.constructor = ObjY; 

ve:

Yani, @Anurag yorum olarak, bir yeni oluşturulan ObjX nesnesine ObjY.prototype ayarlayabilirsiniz Yukarıdaki satırdaki atama, bu özelliğin yanlış bir şekilde ObjX değerini göstermesini sağlayacağından, ObjY.prototype.constructor değiştirdim.

Önerilen makaleler:

+1

Teşekkür ederiz CMS. Harika bağlantı da. Diğer soru, prototiplerin nasıl atanacağıdır - bu, kurucudan yapılabilir mi? –

+0

@Brian, rica ederim, evet yazım hatası yaşadım! – CMS

+0

@Brian, ObjX'in bir nesnesini ObjY'nin prototipi olarak belirlemiştir. ObjY.prototype = yeni ObjX; '. Mevcut nesnede bulunmayan yöntemler ve özellikler prototip zincirine bakılır. – Anurag