Burada dikkat edilmesi gereken önemli olan şey, Javascript dinamik bir dil olduğundan, her nesnenin aslında sadece yüceltilmiş bir karma haritasıdır ( birkaç istisna dışında ). Ve bir Javascript nesnesindeki her şeye iki şekilde erişilebilir: köşeli ayraç notasyonu ve nokta notasyonu.
Sorunuzun ilk kısmını yanıtlayan iki gösterimi hızlıca ele alacağım ve sonra ikinci kısma geçeceğim.
Parantez gösterimi
Bu mod, diğer programlama dillerindeki hashmaps ve dizilere erişmeye daha benzer. Bu sözdizimini kullanarak herhangi bir bileşene (verilere (diğer nesneler dahil) veya işleve) erişebilirsiniz .
Örneğinizde yaptığınız şey tam olarak budur. Bu 'a'
, bir dize ( C ++ gibi bir dilde olduğu gibi, bir harf hazır bilgisi değil ) var.
Köşeli ayraç gösterimini kullanarak toUpperCase
yöntemine erişirsiniz . Ancak ona erişmek hala yeterli değildir; basitçe alert
, örneğin, Javascript yazmak yöntemi çağırmaz. Bu sadece basit bir ifade. İşlevi çağırmak için parantez eklemeniz gerekir: parametre almadığı alert()
için basit bir iletişim kutusu gösterir undefined
. Şimdi bu bilgiyi kodunuzu deşifre etmek için kullanabiliriz;
alert('a'.toUpperCase());
Hangi çok daha okunabilir.
Aslında, bunu biraz daha iyi anlamanın iyi bir yolu aşağıdaki Javascript'i çalıştırmaktır:
alert(alert)
Bu , ikinci uyarıyı yürütmeden alert
de bir işlev nesnesi ileterek çağırır alert
. Gösterilenler (en azından Chrome 26'da) aşağıdakilerdir:
function alert() { [native code] }
Arayan:
alert(alert())
içeren iki ardışık mesaj kutusu gösterir undefined
. Bunu açıklamak kolaydır: önce iç alert()
yürütülür, gösterir undefined
(çünkü herhangi bir parametresi yoktu) ve hiçbir şey döndürmez. Dış alarm, iç alarmın dönüş değerini alır - bu hiçbir şey değildir ve ayrıca undefined
bir mesaj kutusunda da gösterilir .
JsFiddle'daki tüm vakaları deneyin!
Nokta gösterimi
Bu, bir nesnenin üyelerine dot ( .
) operatörü kullanılarak erişilmesini sağlayan daha standart bir yaklaşımdır . Kodunuz nokta gösteriminde şöyle görünecektir:
alert('a'.toUpperCase())
Çok daha okunabilir. Peki nokta gösterimini ne zaman kullanmalıyız ve ne zaman parantez gösterimini kullanmalıyız?
karşılaştırma
İki yöntem arasındaki temel fark semantiktir. Başka ayrıntılar da var, ama bir saniye içinde bunlara ulaşacağım. En önemlisi, gerçekte yapmak istediğiniz şeydir - temel kural, bir nesnenin sahip olduğu iyi kurulmuş alanlar ve yöntemler için nokta gösterimini ve nesnenizi bir karma harita olarak kullandığınızda parantez gösterimini kullanmanızdır. .
Bu kuralın neden bu kadar önemli olduğuna dair harika bir örnek, örneğinizde gösterilebilir - kod, nokta gösteriminin çok daha mantıklı olacağı bir yerde parantez gösterimi kullandığından, kodun okunmasını zorlaştırır. Ve bu kötü bir şey, çünkü kod yazıldığından çok daha fazla okunur .
Bazı durumlarda, nokta gösterimini kullanmak daha mantıklı olsa bile, braket gösterimini kullanmanız gerekir :
bir nesnenin bir üyesinin bir veya daha fazla boşluk veya başka bir özel karakter içeren bir adı varsa, nokta gösterimini kullanamazsınız: foo.some method()
çalışmıyor, ancak çalışıyor foo["some method"]()
;
bir nesnenin üyelerine dinamik olarak erişmeniz gerekiyorsa, köşeli ayraç gösterimi de takılı kalırsınız;
Misal:
for(var i = 0; i < 10; ++i) {
foo["method" + i]();
}
Sonuç olarak, nesneyi karma eşleme ( foods["burger"].eat()
) olarak kullanırken köşeli parantez sözdizimini ve "gerçek" alanlar ve yöntemlerle ( enemy.kill()
) çalışırken nokta sözdizimini kullanmanız gerekir . Javascript dinamik bir dil olduğundan, bir nesnenin "gerçek" alanları ve yöntemleri ile içinde saklanan "diğer" veriler arasındaki çizgi oldukça bulanıklaşabilir. Ama onları kafa karıştırıcı yollarla karıştırmadıkça, iyi olmalısın.
Şimdi, sorunuzun geri kalanına (sonunda!: P).
yöntemin her zaman obj üyesi olacağından nasıl emin olabilirim
Yapamazsın. Dene. derp
Bir dizgiyi aramayı deneyin . Şu satırlarda bir hata alırsınız:
Uncaught TypeError: Object a has no method 'derp'
HERHANGİ BİR nesne üzerinde HERHANGİ yöntemleri çağırmak biraz genel bir işlevdir. Ancak bu, belirtilen yöntemin belirtilen nesnenin zaten örtülü bir üyesi olacağı anlamına mı geliyor?
Evet, sizin durumunuzda olması gerekir. Aksi takdirde yukarıda bahsettiğim hatayla karşılaşırsınız. Ancak, yok olması kullanmaya return obj[method]();
içinde callMethod()
işleve. Daha sonra harita işlevi tarafından kullanılan kendi işlevlerinizi ekleyebilirsiniz. İşte tüm harfleri büyük harfe dönüştüren sabit kodlanmış bir yöntem:
function makeCap()
{
return function(obj) {
return obj.toUpperCase();
}
}
var caps2 = map(['a', 'b', 'c'], makeCap()); // ['A','B','C']
console.log(caps2)
Bağlandığınız öğreticideki kod kısmi işlevler kullanır . Kendi başlarına zor bir kavram. Bu konuda daha fazla şey okumak, işleri yapabileceğimden daha açık hale getirmemize yardımcı olacaktır.
Not: Bu, burada kaynaktaki sorudaki kod tarafından kullanılan harita işlevinin kodudur .
function map(arr, iterator) {
var narr = [];
for (var i = 0; i < arr.length; i++) narr.push(iterator(arr[i], i));
return narr;
}
arr[5]
. : Geçerli bir tanımlayıcı adlar nokta işaretini kullanabilirsiniz sayılar isearr.5
.