2010-01-04 23 views
5

Kodum için işlevsel OOP stilini kullanmayı tercih ediyorum (modül modeline benzer), çünkü "yeni" anahtar kelimeden ve "bu" anahtar kelimesinin kapsamındaki tüm sorunlardan kaçınmam için bana yardımcı oluyor geri aramaları.JavaScript'te işlevsel OOP stili hakkında soru

Ama bununla ilgili birkaç küçük sorunla karşılaşıyorum. Bir sınıf oluşturmak için aşağıdaki kodu kullanmak istiyorum.

namespace.myClass = function(){ 
    var self = {}, 
     somePrivateVar1; 

    // initialization code that would call 
    // private or public methods 
    privateMethod(); 
    self.publicMethod(); // sorry, error here 

    function privateMethod(){} 

    self.publicMethod = function(){}; 

    return self; 
} 

Sorun şu ki, bu işlevler henüz tanımlanmadığı için, başlatma kodumdaki genel yöntemleri arayaamıyorum. Açık çözüm, bir init yöntemi oluşturmak ve "kendi kendine geri dönüş" hattından önce çağırmak olacaktır. Ama belki daha zarif bir çözüm biliyor musun?

Ayrıca, genellikle bu desende mirasla nasıl başa çıkıyorsunuz? Aşağıdaki kodu kullanıyorum ama fikirlerinizi ve önerilerinizi duymak isterim.

namespace.myClass2 = function(){ 
    var self = namespace.parentClass(), 
     somePrivateVar1;    

    var superMethod = self.someMethod; 
    self.someMethod = function(){ 
    // example shows how to overwrite parent methods 
    superMethod(); 
    }; 

    return self; 
} 

Düzeltme.

+0

Genellikle bir dil tarafından verilen teknikleri kullanmamak bir _bad_ düşüncesidir. Bu, yeni olanı atlamamanız gerektiği anlamına gelir, bu sadece Javascript'te yapıldığı yoldur ve muhtemelen bu özel dildeki en iyi yoldur. –

+0

Neden aramayı denemeden önce, neden en üstteki yöntemleri tanımlayamıyorsunuz? –

+0

Gs, özel üyeler ile nesneler oluşturmak için kapaklar kullanarak bir dil tarafından verilen bir teknik olduğunu düşünüyorum. Douglas Crockford bile onu savunmaktadır. Daha önce bazı performans testleri yaptım ve az miktarda nesne için gerçekten önemli değil. (http://valums.com/b/) Ama benim için bir kod temizleyici yapar. –

cevap

0

Neredeyse her yorum katılıyorum ya kadar sağlamış ölçekteki fakat daha Tim'in cevabı bir adım atmak için - Eğer tanımlandı önce yöntemi çağırmak isterdim neden diye sorguladı, ama yine de bir çözüm sundu, sana öneririm oysa değil çağrı tanımlamadan önce (Ben iyi bir uygulama olarak kabul edilir önce deklare en azından onu tanımlayan veya bir yöntemi çağırmak nereye herhangi bir dil bilmiyorum), bu yüzden nasıl olmalıdır hakkında:

namespace.myClass = function(){ 
    //declare private vars (and self) first 
    var self = {}, 
     somePrivateVar1; 

    //then declare private methods 
    function privateMethod(){} 

    //then public/privileged methods 
    self.publicMethod = function(){}; 

    // THEN (and only then) add your 
    // initialization code that would call 
    // private or public methods 
    privateMethod(); 
    self.publicMethod(); // no error any more 

    //then return the new object 
    return self; 
} 

Bunun sizin için işe yaramayacağının belli bir nedeni var mı?

+0

Teşekkür ederim, bu işe yarayacak, ancak çok yaygın olduğu için kurucuyu üstte bırakmayı tercih ederim ve diğer programcıların alışkanlıklarını kırmak istemiyorum. –

1

Çeşitli sorular böyle sebebini gibi bana oluşur: OOP bu tarzı tercih etme nedenleri, aşağıdaki soruları bakabilirsiniz ne istedi olanlar için new operatöründen kaçınmak ve neden tanımlanmadan önce işlevlerini çağırmak istiyorsunuz. Ancak, bunları bir kenara bırakmak, aşağıdaki gibi bir şey hakkında nasıl bir şey?

namespace.myClass = function(){ 
    var somePrivateVar1; 
    var self = {}; 

    // initialization code that would call 
    // private or public methods 
    privateMethod(); 
    publicMethod(); 

    function privateMethod(){} 
    function publicMethod(){} 

    self.publicMethod = publicMethod; 
    return self; 
} 
+0

Teşekkürler, bu yaklaşımdaki problemlerden biri, sınıfınızdaki geçerli bir nesneye referansınız olmamasıdır. Ama benim örneğimde, bir nesneyi kendini bir değişkene başka bir işleve geçirmek mümkün oldu, ör. someFunctionThatRegistersAnObject (öz); –

+0

Cevabınızı oylamaya çalıştım, ancak stackoverflow bir hata gösteriyor "Bu yanıtı düzenlenmişse, değiştirilmek için çok yaşlı oy verin". Bu bir hata mı? –

+0

@valums: Yanıt, yorumunuzu adreslemek için değiştirildi. SO hatası hakkında emin değilim, ancak oylarınızı değiştirebilmeniz gerekiyor, şimdi cevabı düzenledim. –

0

Bu, bahsettiğim çözümdür. Yorumlarınız kabul edilir.

namespace.myClass = function(){ 
    var self = {}, 
     somePrivateVar1; 

    function init(){ 
    privateMethod(); 
    self.publicMethod(); 
    } 

    function privateMethod(){} 
    self.publicMethod = function(){}; 

    init(); 
    return self; 
} 
+1

Bu, işe yarayacak ve eğer baştan başa kodlama koduna sahip olmaya karar verdiyseniz, herhangi bir yönteminizi beyan etmeden önce, söyleyebileceğim kadarıyla gitmenin tek yolu olacaktır. Benim tek yorumum, bunun "zarif" değil, istediğin şey buydu, ancak benim kişisel * görüşüm, yöntemin "nasıl" görünmesini istediğine dair ölçütünün, yine de bu ölçüt içinde değil - orada olan şey muhtemelen en iyi çözümdür. – Graza

2

İstediğiniz şekilde sınıflar ilan size yardımcı olacaktır Zet.js kitaplığını kullanabilirsiniz.