2013-07-15 16 views
10

Özel ve genel yöntemlerle bir nesne oluşturmak için bir kapatma kullanıyorum.JavaScript'te özel işlevler alabilir misiniz?

var Dog = (function() { 
    function Dog() {} 

    var size = 'big'; 

    var _privateSaySize = function() { 
     return 'I am a ' + size + ' dog.'; 
    } 

    Dog.prototype.publicSaySize = function() { 
     return _privateSaySize(); 
    } 

    return Dog; 
})(); 

Ama şimdi sadece özel fonksiyonlara sahip bir nesne var istiyorum ve bu başka bir obje tarafından devralınan - Bu şuna benzer. Ancak bu JavaScript'de mümkün mü?

+1

Bu işlev nedir? Dog = (function() {})() '? – Amberlamps

+2

'private' üyeleri, OOP'yi destekleyen _any_ dilinde tanımlandıkları bir sınıf içinde _only_ görünürler. Yapmaya çalıştığın şeyi anlamıyorum. – Leri

+0

Genel olarak hayır, ancak "özel işlevinize", "notSoPrivateSaySize = new Dog() aracılığıyla kolayca erişilebilir.publicSaySize(); ' – Bergi

cevap

1

Bir örneğin, başka bir özel durumun özel durumunu mi devralmasını istiyorsunuz? Bunu JavaScript'de yapabileceğinizden emin olun. aşağıdaki gibi

var Dog = (function() { 
    function Dog() { 
     if (this instanceof Dog) { 
      // constructor code 
     } else return Object.create(private); 
    } 

    var public = Dog.prototype, private = Object.create(public, { 
     size: { 
      value: "big" 
     } 
    }); 

    public.saySize = weakBind(function (private) { 
     return "I am a " + private.size + " dog."; 
    }, public, private); 

    return Dog; 
}()); 

Artık bir köpek oluşturabilirsiniz: şu şekildedir:

function weakBind(functable, prototype, state) { 
    return function() { 
     return functable.apply(this, Object.getPrototypeOf(this) === prototype ? 
      [state].concat(Array.prototype.slice.call(arguments)) : arguments); 
    }; 
} 

Şimdi bizim temel sınıfını oluşturabilirsiniz: Önce bir yarar fonksiyonunu tanımlamak gerekir

var dog = new Dog; 
alert(dog.saySize()); // I am a big dog. 
alert(dog.size);  // undefined 

Biz özel durumu aşağıdaki gibi alabilir:

aşağıdaki gibi 210

Artık bir chihuahua oluşturabilirsiniz:

var chi = new Chihuahua; 
alert(chi.saySize()); // I am a small dog. 
alert(chi.size);   // undefined 

demo izleyin: http://jsfiddle.net/b3Eyn/

Not: Sadece JavaScript özel durumu devralır mümkün olduğunu göstermek için bu cevabı yazdım. Ancak bu deseni kullanmamanızı tavsiye ederim. Kodunuzu iyi tasarlarsanız, ilk etapta özel durumu devralmanız gerekmeyecektir.

8

Hayır, Yapamazsınız.

JavaScript devralma prototip tabanlı olduğundan, yalnızca prototip yöntemlerini "genişletebilirsiniz".

+0

Anlaşmalı. Pek çok JS geliştiricisinin, kamu API'sinin bir parçası ya da başka bir şekilde korunmadığını ya da başka bir şekilde API'nın bir parçası olmadığını belirtmek için bir alt çizgi ile başka bir şekilde kamu yöntemlerini öncelemesiyle tehlikeye atılmaya değer. Geliştiriciler isterlerse onları değiştirmeyi seçebilirler, ancak bu kendi riskidir. Dürüst olmak gerekirse, JS'de herkese açık bir nesneyi güvence altına almak, kütüphanenizi kullanan herkesin herhangi bir kamu işlevinin üzerine yazabileceği gibi, hatta paylaşılan nesneleri/prototipleri de kapatabildiği için tamamen boş bir çabadır. Sadece baş ağrılarına değmez. –

2

Tür ... Bergi'nin belirttiği gibi, erişim, kapsam tarafından tanımlanır; böylece, mirasçıyı ebeveynin hemen içinde tanımlarsanız, kabaca istediğiniz şeyi alabilirsiniz.

var BarkingDog; 
var Dog = (function() { 
    function Dog() {} 

    var size = 'big'; 

    var _privateSaySize = function() { 
     return 'I am a ' + size + ' dog.'; 
    }; 

    Dog.prototype.publicSaySize = function() { 
     return _privateSaySize(); 
    }; 

    BarkingDog = (function() { 
     function BarkingDog() {} 

     var say = 'woof'; 

     BarkingDog.prototype = new Dog(); 

     BarkingDog.prototype.bark = function() { 
      return _privateSaySize() + ' ' + say; 
     }; 

     return BarkingDog; 

    })(); 

    return Dog; 
})(); 

var myDog = new BarkingDog(); 
console.log(myDog.bark()); 
console.log(myDog.publicSaySize()); 

Gerçi ... neden isteyeyim Emin değilim: D JavaScript

5

değişkenler (fonksiyonların) gizlilik fonksiyonu kapsamları aracılığıyla yapılır. Dışarıdan onlara ancak kapama kapsamından ihraç ediliyorsa erişebilirsiniz, başka yol yoktur.

Yöntemleri özel işlevlere erişimi olan bir nesneyi yapmak için, onu yalnızca aynı kapsamda yerleştirmeniz gerekir. Nesnenin diğer nesnelerden miras kaldığı oldukça alakasız.

function Dog() {} 
function Dalmatian() {} 
Dalmation.prototype = Object.create(Dog.prototype); 
Dalmation.prototype.size = "big"; 
function Dackel() {} 
Dackel.prototype = Object.create(Dog.prototype); 
Dackel.prototype.size = "small"; 

(function() { 
    // private function 
    function say(s) { 
     console.log("I'm a "+s+" dog"); 
    } 
    // both accessible from the Dog and Dackel public methods 
    Dog.prototype.saySize = function() { 
     say(this.size || "normal"); 
    }; 
    Dackel.prototype.saySize = function() { 
     say(this.size + " but loud"); 
    }; 
})(); 
new Dog().saySize(); 
new Dalmatian().saySize(); 
new Dackel().saySize(); 
0

Nokta gösteriminin kullanılmasını engelleyebilirsiniz. Ama bu gerçekten özel değil.

var Dog = (function() { 
    function Dog() {} 

    var size = 'big'; 

    Dog.prototype['-privateSaySize'] = function() { 
     return 'I am a ' + size + ' dog.'; 
    } 

    Dog.prototype.publicSaySize = function() { 
     return this['-privateSaySize'](); 
    } 

    return Dog; 
})() 
+0

Bir özelliğin "içselliğini" göstermek için, alt çizgi '_ 'eksi kullanılmaz. Bu şekilde parantez gösteriminden kaçınabilirsiniz… – Bergi

+0

@Bergi Bu nokta budur. Bir eksi kullandım, çünkü bu şekilde nokta gösterimini kullanamazsınız, bu nedenle sadece parantez notasyonu kullanılarak kullanılabilir. – boskop

+0

Ve bu nasıl yardımcı olur? Gizliliği ifade etmek için [sözleşmenin alt çizgilerini kullanmaktır] (http://stackoverflow.com/q/4484424/1048572). Braket notasyonu hiçbir şeyi değiştirmez. – Bergi

İlgili konular