Öncelikle, JavaScript'in sınıf tabanlı bir dil yerine öncelikle bir prototip dili olduğunu unutmayın 1 . bir sınıf değil, bir işlev, bir nesne. Bir nesne örneğini gelen kullanarak bu fonksiyonu standart bir cepten dilde bir sınıfa benzer bir şey yaratmak sağlayacak anahtar kelime.Foo
new
__proto__
Çapraz tarayıcı desteği zayıf olduğu için çoğu zaman görmezden gelmeyi öneririm ve bunun yerine nasıl prototype
çalıştığını öğrenmeye odaklanırım .
İşlev 2'den oluşturulan bir nesnenin örneğine sahipseniz ve üyelerinden birine (yöntemler, öznitelikler, özellikler, sabitler vb.) Herhangi bir şekilde erişirseniz, erişim (a) işlevini bulana kadar prototip hiyerarşisinden aşağı akar veya (b) başka bir prototip bulamaz.
Hiyerarşi çağrılan nesnede başlar ve sonra prototip nesnesini arar. Prototip nesnesinin bir prototipi varsa, prototip yoksa tekrarlanır undefined
.
Örneğin:
foo = {bar: 'baz'};
console.log(foo.bar); // logs "baz"
foo = {};
console.log(foo.bar); // logs undefined
function Foo(){}
Foo.prototype = {bar: 'baz'};
f = new Foo();
console.log(f.bar);
// logs "baz" because the object f doesn't have an attribute "bar"
// so it checks the prototype
f.bar = 'buzz';
console.log( f.bar ); // logs "buzz" because f has an attribute "bar" set
Bana en azından bir şekilde bu "temel" parçaları daha önce anladığınız gibi geliyor, ama emin olmak için onları açık hale getirmem gerekiyor.
JavaScript'te her şey bir nesnedir 3 .
her şey bir nesnedir.
function Foo(){}
sadece yeni bir fonksiyon tanımlamakla kalmaz, aynı zamanda erişilebilecek yeni bir fonksiyon nesnesi tanımlar Foo
.
Bu yüzden Foo
'in prototipine erişebilirsiniz Foo.prototype
.
Ayrıca ayarlandığında yapabilirsiniz Ne fazla işlevleri üzerinde Foo
:
Foo.talk = function () {
alert('hello world!');
};
Bu yeni işleve aşağıdakiler kullanılarak erişilebilir:
Foo.talk();
Umarım şimdi bir işlev nesnesindeki işlevler ve statik bir yöntem arasında bir benzerlik fark edersiniz.
f = new Foo();
Bir sınıf örneği oluşturmak, sınıf Foo.prototype.bar = function(){...}
için paylaşılan bir yöntem tanımlamak ve sınıf Foo.baz = function(){...}
için genel bir statik yöntem tanımlamak olarak düşünün .
ECMAScript 2015, okunması daha kolay olmakla birlikte, bunların uygulanmasını kolaylaştırmak için bu tür bildirimler için çeşitli sözdizimsel şeker tanıttı. Dolayısıyla önceki örnek şu şekilde yazılabilir:
class Foo {
bar() {...}
static baz() {...}
}
hangi bar
olarak adlandırılmasını sağlar :
const f = new Foo()
f.bar()
ve baz
şu şekilde adlandırılmalıdır:
Foo.baz()
1: class
ECMAScript 5 belirtiminde bir "Gelecek Ayrılmış Word'dür " , ancak ES6 class
anahtar kelimeyi kullanarak sınıfları tanımlama yeteneğini sunar .
2: temelde bir kurucu tarafından yaratılan bir sınıf örneği, ancak sizi yanıltmak istemediğim birçok nüanslı farklılık var
3: İlkel değerler şunlardır -ki undefined
, null
, boolean, sayı ve dizeleri-etmediler teknik olarak çünkü onlar konum alt düzey dil uygulamaları nesneleri. Booleanlar, sayılar ve karakter dizileri hala prototip zinciri ile nesneymiş gibi etkileşime girer, bu nedenle bu cevabın amaçları için, tam olarak olmasalar bile onları "nesneler" olarak değerlendirmek daha kolaydır.
Foo.talk = function ...