giriiş
Sınıflar, nesneler oluşturmak için bir şablondur. Verileri, bu veriler üzerinde işlem yapmak için kodla birlikte kapsüllerler. JS'deki sınıflar prototipler üzerine kuruludur, ancak sınıflara özgü bazı sözdizimleri ve anlamsal yapıları da vardır.
Sınıflar esasen "özel fonksiyonlardır" ve fonksiyon ifadelerini ve fonksiyon bildirimlerini tanımlayabildiğiniz gibi, bir sınıf da iki şekilde tanımlanabilir: bir sınıf ifadesi veya bir sınıf bildirimi.
// Declaration
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
// Expression; the class is anonymous but assigned to a variable
const Rectangle = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
// Expression; the class has its own name
const Rectangle = class Rectangle2 {
constructor(height, width) {
this.height = height;
this.width = width;
}
};Fonksiyon bildirimleri gibi, sınıf bildirimleri de anonim olabilir veya atandıkları değişkenden farklı bir ada sahip olabilir. Ancak, fonksiyon bildirimlerinin aksine, sınıf bildirimleri let veya const ile aynı ölü bölge zaman kısıtlamalarına sahiptir ve kaldırılmamış gibi davranırlar.
Sınıf gövdesi
Bir sınıfın gövdesi, süslü parantezler {} içinde yer alan kısımdır. Sınıfın üyelerini, örneğin metotları veya oluşturucuları burada tanımlarsınız.
Bir sınıfın gövdesi, "use strict" yönergesi olmadan bile, sıkı modda çalıştırılır.
Bir sınıf unsuru üç açıdan tanımlanabilir:
- Tür: Alıcı, Regülatör, Yöntem veya Alan
- Konum: Statik veya Örnek
- Görünürlük: Genel veya Özel
Yapıcı
Yapıcı yöntem, bir sınıfla oluşturulmuş bir nesneyi oluşturmak ve başlatmak için kullanılan özel bir yöntemdir. Bir sınıfta yalnızca "yapıcı" adlı bir özel yöntem bulunabilir; sınıf, birden fazla yapıcı yöntem örneği içeriyorsa, SyntaxError hatası oluşur.
Bir constructor, süper sınıf constructor'ını çağırmak için super anahtar sözcüğünü kullanabilir.
Oluşturucunun içinde örnek özellikleri oluşturabilirsiniz:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}Alternatif olarak, örneğinizin özelliklerinin değerleri oluşturucu argümanlarına bağlı değilse, bunları sınıf alanları olarak tanımlayabilirsiniz.
Statik başlatma blokları
Statik bloklar, başlatma sırasında ifadelerin değerlendirilmesi de dahil olmak üzere statik özelliklerin esnek bir şekilde başlatılmasına olanak tanırken, özel kapsama erişime de izin verir.
Birden fazla statik blok bildirilebilir ve bu bloklar statik alanların ve yöntemlerin bildirimleriyle aralara serpiştirilebilir (tüm statik öğeler bildirim sırasına göre değerlendirilir).
Yöntemler
Yöntemler, bir sınıfın her örneğinin prototipinde tanımlanır ve tüm örnekler tarafından paylaşılır. Yöntemler basit işlevler, eşzamansız işlevler, üreteç işlevleri veya eşzamansız üreteç işlevleri olabilir. Daha fazla bilgi için Yöntem Tanımları bölümüne bakın.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
*getSides() {
yield this.height;
yield this.width;
yield this.height;
yield this.width;
}
}
const square = new Rectangle(10, 10);
console.log(square.area); // 100
console.log([...square.getSides()]); // [10, 10, 10, 10]Statik yöntemler ve alanlar
static anahtar sözcüğü, bir sınıf için statik bir yöntem veya alan tanımlar. Statik özellikler (alanlar ve yöntemler), her örnekte değil, sınıfın kendisinde tanımlanır. Statik yöntemler genellikle bir uygulama için yardımcı işlevler oluşturmak için kullanılırken, statik alanlar önbelleğe alma, sabit yapılandırma veya örnekler arasında tekrarlanması gerekmeyen diğer veriler için kullanışlıdır.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static displayName = "Point";
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
p1.displayName; // undefined
p1.distance; // undefined
p2.displayName; // undefined
p2.distance; // undefined
console.log(Point.displayName); // "Point"
console.log(Point.distance(p1, p2)); // 7.0710678118654755Saha duyuruları
Sınıf alanı bildirim sözdizimiyle, constructor örneği aşağıdaki gibi yazılabilir:
class Rectangle {
height = 0;
width;
constructor(height, width) {
this.height = height;
this.width = width;
}
}Sınıf alanları değişken değil, nesne özellikleri gibidir, bu yüzden bunları bildirmek için const gibi anahtar sözcükler kullanmayız. JavaScript'te, private özellikler özel bir tanımlayıcı sözdizimi kullanır, bu nedenle public ve private gibi değiştirici anahtar sözcükler de kullanılmamalıdır.
Yukarıda görüldüğü gibi, alanlar varsayılan değerlerle veya varsayılan değerler olmadan tanımlanabilir. Varsayılan değerleri olmayan alanlar varsayılan olarak tanımlanmaz. Alanları önceden tanımlayarak, sınıf tanımları daha iyi belgelenir ve alanlar her zaman mevcut olur; bu da optimizasyona yardımcı olur.
Daha fazla bilgi için Genel Sınıf Alanlarına bakın.
Özel mülkler
Özel alanlar kullanılarak tanımlama aşağıdaki şekilde değiştirilebilir.
class Rectangle {
#height = 0;
#width;
constructor(height, width) {
this.#height = height;
this.#width = width;
}
}Özel alanlara sınıf dışından başvurmak bir hatadır. Bunlar yalnızca sınıf gövdesinden okunabilir veya yazılabilir. Sınıf dışında görünmeyen öğeler tanımlayarak, sınıfınızın kullanıcılarının sürümden sürüme değişebilen dahili öğelere bağımlı kalmamasını sağlarsınız.
Özel alanlar yalnızca bir alan bildiriminde önceden bildirilebilir. Normal özellikler gibi, daha sonra kendilerine atama yapılarak oluşturulamazlar.
Daha fazla bilgi için Özel Mülkiyet bölümüne bakınız.
Miras
extends anahtar sözcüğü, bir sınıfı başka bir oluşturucunun (sınıf veya fonksiyon) çocuğu olarak oluşturmak için sınıf bildirimlerinde veya sınıf ifadelerinde kullanılır.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(`${this.name} barks.`);
}
}
const d = new Dog("Mitzie");
d.speak(); // Mitzie barks.Alt sınıfta bir constructor varsa, kullanmadan önce super() metodunu çağırmalıdır. super anahtar sözcüğü, üst sınıfla ilgili yöntemleri çağırmak için de kullanılabilir.
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(`${this.name} roars.`);
}
}
const l = new Lion("Fuzzy");
l.speak();
// Fuzzy makes a noise.
// Fuzzy roars.Değerlendirme sırası
Bir sınıf bildirimi veya sınıf ifadesi değerlendirildiğinde, çeşitli bileşenleri aşağıdaki sırayla değerlendirilir:
- Varsa, genişletilmiş ifade önce değerlendirilir. Geçerli bir oluşturucu işlevi veya null olarak değerlendirilmelidir, aksi takdirde bir TypeError hatası oluşur.
- Oluşturucu yöntemi çıkarılır ve oluşturucu mevcut değilse, varsayılan uygulama ile değiştirilir. Ancak, oluşturucu tanımı yalnızca bir yöntem tanımı olduğundan, bu adım görünür değildir.
- Sınıf öğelerinin özellik anahtarları, tanımlandıkları sırayla değerlendirilir. Özellik anahtarı değerlendirilirse, bu değerle değerlendirilen ifade, sınıfı çevreleyen bu değere ayarlanır (sınıfın kendisine değil). Özellik değerlerinden hiçbiri henüz değerlendirilmemiştir.
- Yöntemler ve erişim araçları, tanımlandıkları sırayla yüklenir. Örnek yöntemler ve erişim araçları, geçerli sınıfın prototip özelliğine yüklenirken, statik yöntemler ve erişim araçları sınıfın kendisine yüklenir. Özel örnek yöntemler ve erişim araçları, daha sonra doğrudan örneğe yüklenmek üzere ayrılmıştır. Bu adım görünür değildir.
- Sınıf artık uzantılar tarafından belirtilen prototip ve oluşturucu tarafından belirtilen uygulama ile başlatılır. Yukarıdaki tüm adımlarda, değerlendirilen bir ifade sınıf adına erişmeye çalışırsa, sınıf henüz başlatılmadığı için bir ReferenceError hatası oluşur.
- Sınıf elemanlarının değerleri bildirim sırasına göre değerlendirilir:
- Her örnek alanı (genel veya özel) için, başlatıcı ifadesi saklanır. Başlatıcı, örnek oluşturulduğunda, oluşturucunun başlangıcında (temel sınıflar için) veya super() çağrısı dönmeden hemen önce (türetilmiş sınıflar için) değerlendirilir.
- Her sabit alan (public veya private) için, bu kümeyle başlatılması sınıfın kendisine değerlendirilir ve özellik sınıf üzerinde oluşturulur.
- Statik başlatma blokları sınıfın kendisinde bu küme ile değerlendirilir.
Örnekler
Bunu örnek ve statik yöntemlerle bağlamak
Statik veya örnek bir yöntem, bir değer belirtilmeden çağrıldığında (örneğin, yöntem bir değişkene atanıp ardından çağrılarak), değer yöntem içinde tanımsız hale gelir. "using strict" yönergesi olmasa bile bu davranış aynıdır, çünkü sınıf gövdesindeki kod her zaman strict modunda yürütülür.
class Animal {
speak() {
return this;
}
static eat() {
return this;
}
}
const obj = new Animal();
obj.speak(); // the Animal object
const speak = obj.speak;
speak(); // undefined
Animal.eat(); // class Animal
const eat = Animal.eat;
eat(); // undefinedYukarıdakileri, sıkı olmayan durumda geleneksel fonksiyon tabanlı sözdizimini kullanarak yeniden yazarsak, bu yönteme yapılan çağrılar otomatik olarak globalThis ile sınırlandırılır. Sıkı durumda ise, this'nin değeri tanımsız kalır.
function Animal() {}
Animal.prototype.speak = function () {
return this;
};
Animal.eat = function () {
return this;
};
const obj = new Animal();
const speak = obj.speak;
speak(); // global object (in non–strict mode)
const eat = Animal.eat;
eat(); // global object (in non-strict mode)









