JavaScript dünyanın en yanlış anlaşılan programlama dilidir. Nesnelerin özel örnek (instance) değişkenlerine ve metodlarına sahip olamayacağı için bilgi gizleme özelliğinden yoksun olduğuna inanılıyor. Ama bu bir yanlış anlaşılmadır. JavaScript nesneleri özel üyelere (private member) sahip olabilir. Bu şekilde gösterebiliriz:
Nesneler
JavaScript’in temeli nesnelerdir. Diziler nesnedir. Fonksiyonlar nesnedir. Nesneler nesnedir. Peki nesneler nedir? Nesneler, ad-değer (name-value) çiftlerinden oluşan koleksiyonlardr. Adlar string’tir, değerler ise string, number, boolean ve nesne (dizi ve fonksiyonlar da dahil) olabilir. Nesneler genellikle hashtable olarak uygulanır, böylece değerler hızlı bir şekilde alınabilir.
Eğer bir değer fonksiyon ise, bunu bir metot olarak sayabiliriz. Bir nesnenin metodu çağrıldığında this
değişkenine o nesne atanır. Bu metot daha sonra this
değişkeni aracılığıyla örnekteki diğer değişkenlere erişebilir.
Nesneler, nesneleri başlatan fonksiyonlar olan yapıcılar (constructor) tarafından oluşturulabilir. Yapıcılar, statik değişkenler ve metodlar dahil olmak üzere sınıfların diğer dillerde sağladığı özellikleri sağlar.
Genel (Public)
Bir nesnenin üyelerinin tümü genel üyelerdir. Herhangi bir fonksiyon bu üyelere erişebilir, bunları değiştirebilir veya silebilir ya da yeni üyeler ekleyebilir. Bir nesneye yeni üyeleri eklemenin iki ana yolu vardır:
Yapıcıda
Bu teknik genellikle genel örnek değişkenlerini (public instance variable) başlatmak için kullanılır. Yapıcının this
değişkeni, nesneye üye eklemek için kullanılır.
function Container(param) {
this.member = param;
}
Yani, yeni bir nesne oluşturursak:
var myContainer = new Container('abc');
myContainer.member
üye değişkeninin değeri 'abc'
olacak.
Prototipte
Bu teknik genellikle genel metodlar eklemek için kullanılır. Bir üye istendiğinde ve nesnenin kendisinde bulunmadığında, nesnenin yapıcısının prototype
üyesinden alınır.
Container.prototype.stamp = function (string) {
return this.member + string;
}
myContainer.stamp('def');
Metodu bu şekilde çalıştırdığımızda 'abcdef'
sonucunu döner.
Özel (Private)
Özel üyeler yapıcı tarafından oluşturulur. Yapıcının var
ile yazılmış sıradan değişkenleri ve parametreleri özel üyeler haline gelir.
function Container(param) {
this.member = param;
var secret = 3;
var that = this;
}
Buradaki yapıcı üç tane özel örnek değişkeni oluşturuyor: param
, secret
ve that
. Nesneye bağlıdırlar, ancak ne dışarıdan ne de nesnenin kendi genel metodlarından erişilebilirler. Özel metodlar tarafından erişilebilirler. Özel metodlar, yapıcının iç fonksiyonlarıdır.
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
}
Özel metot dec
, secret
örnek değişkenini kontrol ediyor. Eğer sıfırdan büyükse secret
değişkenini azaltıp true
dönüyor. Aksi takdirde ise false
dönüyor. Bu nesneyi üç kullanımla sınırlandırmak için kullanılabilir.
Genel kurala göre bir that
özel değişkenini tanımlıyoruz. Bu, nesneyi özel metodların erişimine açmak için kullanılır. İç fonksiyonlar için this
değerinin yanlış ayarlanmasına neden olan ECMAScript Dil Spesifikasyon’undaki bir hata için geçici bir çözüm olarak bu uygulanır.
Özel metodlar, genel metodlar tarafından çağrılamazlar. Özel metodları kullanışlı hale getirmek için ayrıcalıklı yöntemleri (privileged method) uygulamamız gerekiyor.
Ayrıcalıklı (Privileged)
Ayrıcalıklı bir metot, özel değişkenlere ve metodlara erişebilir ve kendisi de genel metodlara ve dışarıya açıktır. Ayrıcalıklı bir metodu silmek veya yenisiyle değiştirmek mümkündür, ancak onun içeriğini değiştirmek veya sırlarını açmaya zorlamak mümkün değildir.
Ayrıcalıklı metodlar, yapıcının içinde this
ile atanır.
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
this.service = function () {
return dec() ? that.member : null;
};
}
service
metodu ayrıcalıklı bir metottur. myContainer.service()
metodu çağrıldığı ilk üç seferde 'abc'
dönecektir. Ondan sonra ise null
dönecek. service
metodu, özel secret
değişkenine erişen özel dec
metodunu çağırır. service
metodu diğer nesne ve metodlara açıktır, ancak özel üyelere direkt erişime izin vermez.
Kapanımlar (Closures)
Bu genel, özel ve ayrıcalıklı üye kalıplarını uygulamak JavaScript’in kapanımlar (closures) özelliği sayesinde mümkündür. Bunun anlamı, bir iç fonksiyonun, dış fonksiyon bir değer geri döndükten sonra bile, dış fonksiyonunu değişkenlerine ve parametrelerine her zaman erişimi olmasıdır. Dilin son derece güçlü bir özelliğidir bu. Bu, How JavaScript Works kitabında açıklanmıştır.
Özel ve ayrıcalıklı üyeler sadece bir nesne başlatıldığında oluşturulabilir. Genel üyeler ise herhangi bir zamanda eklenebilir.
Kalıplar
Genel
function Constructor(...) {
this.membername = value;
}
Constructor.prototype.membername = value;
Özel
function Constructor(...) {
var that = this;
var membername = value;
function membername(...) {...}
}
Not: Aşağıdaki fonksiyon ifadesi
function membername(...) {...}
bunun bir kısaltmasıdır:
var membername = function membername(...) {...};
Ayrıcalıklı
function Constructor(...) {
this.membername = function (...) {...};
}
Bu, Douglas Crockford‘un Private Members in JavaScript adlı orijinal yazısının çevirisidir.