Objeler genelde dünyada var olan Åeyler gibidirler, kullanıcılar, emirler, vs.
let kullanici = {
isim: "İhsan",
yas: 30
};
Kullanıcıların iÅlem yapma yetenekleri vardır: alıÅveriÅ sepeti, giriÅ, çıkıŠvs.
Bu aksiyonlar Javascriptâte özellikler için fonksiyon kullanarak çözülür.
Metod Ãrnekleri
BaÅlangıç olarak kullanici merhaba desin:
let kullanici = {
isim: "İhsan",
yas: 30
};
kullanici.selamVer = function() {
alert("Merhaba");
};
kullanici.selamVer(); // Merhaba
Burada Fonksiyon ifadesi ile fonksiyon yaratıldı ve kullanici.selamVer özelliÄine atandı.
Ardından bu metod çaÄırıldı ve kullanıcı selam verdi.
Bir objenin özelliÄi olan fonksiyona metod denir.
Ãyleyse kullanici objesinin selamVer metodu bulunmaktadır.
Tabii ki metodları önceden tanımlanmıŠfonksiyonlarla da oluÅturabilirsiniz. ÃrneÄin:
let kullanici = {
// ...
};
// önce tanımla
function selamVer() {
alert("Merhaba!");
};
// Sonra bunu metod olarak objeye ekle
kullanici.selamVer = selamVer;
kullanici.selamVer(); // Merhaba!
Varlıkların obje olarak tanımlandıÄı dillere obje tabanlı diller, kısaca: âOOPâ(Objet-Oriented Programming)
OOP kendi baÅına kitaplar dolusu anlatılacak bir konudur. Nasıl doÄru varlıklar seçilmeli? Bu varlıklar arasında nasıl bir iletiÅim olmalı? Mimarisi nasıl olmalı, gibi konuların her birisi ile ilgili ayrı ayrı kitaplar bulunmaktadır. ÃrneÄin âDesign Patterns: Elements of Reusable Object-Oriented Softwareâ by E.Gamma, R.Helm, R.Johnson, J.Vissides or âObject-Oriented Analysis and Design with Applicationsâ by G.Booch, vs. Bu kitapta "object-oriented-programming" adresindeki makale bulunamadı sadece baÅlangıç seviyesinde anlatılacaktır.
Metod Kısayolu
Metodları yaratmak için daha kolay bir kullanım mevcuttur:
// aÅaÄıdaki objeler aynı iÅleri yapar.
let kullanici = {
selamVer: function() {
alert("Merhaba");
}
};
// kısa yolu daha güzel görünüyor deÄil mi?
let kullanici = {
selamVer() { // "selamVer: function()" ile aynı
alert("Merhaba");
}
};
Yukarıda da gösterildiÄi gibi "function" pas geçilerek sadece selamVer() yazılabilir.
DoÄrusunu söylemek gerekirse iki fonksiyonda birbiri ile aynı. Altta yatan farklılık ise kalıtım ile alakalı ki bu da Åimdilik bir sorun teÅkil etmiyor. ÃoÄu durumda kısa yazım tercih edilmektedir.
Metodlarda this kullanımı
Obje metodlarının objelerde bulunan diÄer bilgilere ulaÅması çok büyük bir gerekliliktir.
ÃrneÄin kullanici.selamVer() kullanici ismine ihtiyaç duyar.
Objeye ulaÅabilmek içim metod this kelimesine ihtiyaç duyar.
ânoktadan önceâ yazılan this o objeye referans verir. ÃrneÄin:
let kullanici = {
isim: "İhsan",
yas: 30,
selamVer() {
alert(this.isim);
}
};
kullanici.selamVer(); // İhsan
Yukarıda kullanici.selamVer() fonksiyonu çalıÅtırılırken this kullanici olacaktır.
Teknik olarak this olmadan da objenin özelliklerine eriÅmek mümkündür. Bu dıÅtaki deÄiÅkene referans vererek yapılabilir:
let kullanici = {
isim: "İhsan",
yas: 30,
selamVer() {
alert(kullanici.isim); // "this" yerine "kullanici" kullanılmıÅtır.
}
};
⦠Fakat böyle bir koda güvenilmez. Diyelim ki kullanici objesini kopyaladınız ve yonetici = kullanici yaptınız. Sonra kullanici objesinin üzerine yazdınız bu durumda yanlıŠobjeye eriÅmiÅ olacaksınız. Bir örnekle açıklamak gerekirse:
let kullanici = {
isim: "İhsan",
yas: 30,
selamVer() {
alert( kullanici.isim ); // hataya neden olur
}
};
let yonetici = kullanici;
kullanici = null;
yonetici.selamVer(); // `selamVer()` içerisinde `kullanici` kullanıldıÄından dolayı hata verecektir.
EÄer kullanici.isim yerine this.isim yazmıŠolsaydınız kod çalıÅacaktı.
âthisâ baÄımsız bir Åekilde kullanılabilir.
DiÄer dillerden farklı olarak âthisâ kelimesi yer gözetmeksizin kullanılabilir. Her fonksiyonun içinde kullanılabilir.
AÅaÄıdaki kodda bir yazım hatası yoktur:
function selamVer() {
alert( this.isim );
}
thisâin deÄeri çalıÅma anında deÄerlendirilir. Her Åey olabilir.
ÃrneÄin this farklı objelerden çaÄırıldıklarında deÄerler alabilirler:
let kullanici = { isim: "İhsan" };
let yonetici = { isim: "Macide" };
function selamVer() {
alert( this.isim );
}
// aynı fonksiyonu iki farklı objeye atandı.
kullanici.f = selamVer;
yonetici.f = selamVer;
// iki fonksiyon da farklı `this` e sahip.
// "noktadan" önceki "this" objeye referans verir.
kullanici.f(); // İhsan (this == kullanici)
yonetici.f(); // Yonetici (this == yonetici)
yonetici['f'](); // KöÅeli parantez veya noktalı yazım farketmez, her ikisi de çalıÅır.
this == undefinedAslında fonksiyonu obje olmadan da çaÄırmak mümkündür.
function selamVer() {
alert(this);
}
selamVer(); // tanımsız
Sıkı modda this undefined döndürür. EÄer this.isim yazılırsa hata verir.
Normal modda ise ( use strict unutulursa) this deÄeri global obje olur. Tarayıcı için bu windowdur. Bu konuya daha sonra deÄinilecektir.
Obje olmadan this çaÄırmak normal deÄildir, bir programlama hatasıdır. EÄer fonksiyon this içeriyorsa, o objenin dahilinde çaÄırılabileceÄi anlamı çıkar.
this kullanmanın yan etkileriDiÄer programlama dillerinden geliyorsanız, âbaÄımlı thisâ kullanımına alıÅmıŠolmalısınız. Metod içerisinde kullanılan this her zaman o objeye referans olur.
JavaScriptâte this baÄımsızdır. DeÄeri çalıÅma anında belirlenir, hangi metodda yazıldıÄı önemli deÄildir, önemli olan ânoktadan öncekiâ objedir.
ÃalıÅma anında this kullanılabilmesinin artıları ve eksileri vardır. Bir taraftan fonksiyonlar diÄer objelerde de kullanılabilirken, diÄer yönden bu kadar esneklik hatalara neden olabilmektedir.
Burada amacımız programlama dilininin dizaynının kötü veya iyiliÄi deÄildir. Amaç nasıl çalıÅtıÄını anlayıp, nerelerde yarar nerelerde zarar getirileceÄini bilmektir.
Dahili Ãzellikler: Referans Tipleri
Bu bölüm daha derinlemesine konuları içermektedir.
Daha hızlı ilerlemek istiyorsanız bu bölümü geçebilir veya daha sonraya erteleyebilirsiniz.
Girift metod çaÄrıları this kelimesini kaybedebilir, örneÄin:
let kullanici = {
isim: "İhsan",
selamVer() { alert(this.isim); },
yolcuEt() { alert("Güle Güle"); }
};
kullanici.selamVer(); // Basit metod beklendiÄi gibi çalıÅır
// Åimdi isme göre selamVersin veya yolcuEt'sin.
(kullanici.isim == "İhsan" ? kullanici.selamVer : kullanici.yolcuEt)(); // Hata!
Son satırda kullanıcı ismine göre kullanici.selamVer veya kullanici.yolcuEt cagrilir. kullanici.selamVer () ile çaÄrıldıÄında çalıÅmaz.
Bunun nedeni çaÄrı içerisinde thisâin undefined olmasıdır.
AÅaÄıdaki çalıÅır:
kullanici.selamVer();
AÅaÄıdaki kod metodu çalıÅtırmaz:
(kullanici.isim == "İhsan" ? kullanici.selamVer : kullanici.yolcuEt)(); // Hata!
Neden? EÄer bunun derinliklerine inmek isterseniz öncelikle bakmanız gereken yer obj.method() çaÄrısı olmalıdır.
Peki bu obj.method() cümlesi ne yapar:
'.'özelliÄi alır()bu özelliÄi çalıÅtırır.
Peki this ilk bölümden ikincisine nasıl geçer?
EÄer bu olayı iki farklı satırda gösterecek olursak, this bu durumda kaybolacaktır:
let kullanici = {
isim: "İhsan",
selamVer() { alert(this.isim); }
}
// metodu alma ve çaÄırma iki satırda gösterilecek olursa
let selamVer = kullanici.selamVer;
selamVer(); // hata!, tanımsız
Burada selamVer = kullanici.selamVer fonksiyonu deÄiÅkene atar, sonra son satırdaki yapılan ise tamamen ilkinden farklıdı. Bundan dolayı this bulunmamaktadır.
kullanici.selamVer() çaÄrısının çalıÅabilmesi için bir çözüm bulunmaktadır. '.' fonksiyon deÄil [Referans Tipi] döndürmektedir.(https://tc39.github.io/ecma262/#sec-reference-specification-type)
Referans Tipi âÅartname tipidiâ. DoÄrudan kullanılamaz, dil kendince kullanabilir bu tipleri.
Referans Tipi üç deÄerin birleÅmesi ile oluÅur (base, name, strict):
baseobjedir.nameözelliktir.stricteÄeruse strictkullanılmıÅsatrueolur.
kullanici.selamVer eriÅimi fonksiyon deÄil Referans Tipi döndürür. Sıkı mod kullanıldıÄında kullanici.selamVer aÅaÄıdaki gibi döner:
// Referans Tipi deÄeri
(kullanici, "selamVer", true)
Referans Tipinde () çaÄrıldıÄında obje ve onun metodu hakkında tüm bilgileri alınır ve this (bizim durumumuzda kullanici ) belirlenir.
Atama gibi iÅlemler selamVer = kullanici.selamVer referans tipini tamamen iptal eder, kullanici.selamVer(fonksiyon) deÄerini alır ve bunu paslar. Bu Åekilde de this tanımsız kalır.
Bundan dolayı this in çalıÅabilmesi için metodun doÄrudan obj.metod() Åeklinde veya obj[metod]() Åeklinde çalıÅtırılması gerekmektedir.
Ok fonksiyonlarında âthisâ bulunmamaktadır.
Ok fonksiyonları özeldir: Kendilerinin thisâi bulunmaz. EÄer yine de this kullanırsanız ok fonksiyonu dıÅındaki bölümü this olarak alır.
ÃrneÄin aÅaÄıdaki ok() dıÅarıda bulunan kullanici.selamVer() metodunu kullanmaktadır:
let kullanici = {
isim: "İhsan",
selamVer() {
let ok = () => alert(this.isim);
ok();
}
};
kullanici.selamVer(); // İhsan
Bu ok fonksiyonlarının bir özelliÄidir. Ayrı bir this kullanmak yerine her zaman bir üstteki bölümden this i alması baya kullanıÅlıdır. Ok fonksiyonları bölümü içerisinde bu konu derinlemesine incelenecektir.
Ãzet
- Objeler içerisinde saklanan fonksiyonlara âmetodâ denir.
- Metodlar objelerin
obje.biseylerYap()seklinde çalıÅabilmesini saÄlar. - Metodlar objelere
thisÅekline referans verebilir.
thisâin deÄeri çalıÅma zamanında tanımlanır.
- Fonksiyon tanımlanırken
thiskullanabilir, fakatthisbu metod çalıÅmadıÄı müddetçe bir anlam ifade etmez. - O fonksiyon objeler arasında kopyalanabilir.
- Fonksiyon metod yazım Åekliyle çaÄırıldıÄında
obje.metod(),thisâin deÄeri bu çaÄrı boyuncaobjeâdir.
Ok fonksiyonlarında this bulunmamaktadır. EÄer bu fonksiyonlar içerisinde this çaÄırılırsa bunun deÄeri dıÅarıdan alınır.
Yorumlar
<code>kullanınız, birkaç satır eklemek için ise<pre>kullanın. EÄer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)