Sınıf, nesne yönelimli programlama dillerinde nesnelerin özelliklerini, davranıÅlarını ve baÅlangıç durumlarını tanımlamak için kullanılan Åablonlara verilen addır.
Pratikte, aynı türden birçok nesne oluÅturmamız gerekebilir, kullanıcılar veya malzemeler gibi.
Yapıcı, "new" operatörü, kısmından bildiÄimiz gibi new(yeni) fonksiyonu bize bu konuda yardımcı olabilir.
Ancak modern Javascriptâde bundan daha geliÅmiÅ bir âsınıfâ yapısı var. Bu yapı nesne tabanlı programlamaya yeni ve faydalı özellikler getiriyor.
Sınıf sözdizimi
Temel sözdizimi:
class MyClass {
// class methods
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
Sonra new MyClass() bu metotlarla birlikte yeni bir nesne oluÅturuyor.
constructor() metodu new tarafından otomatik olarak çaÄırılıyor. Bu sayede nesneyi orada tanımlayabiliyoruz.
Ãrnek olarak:
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
// Usage:
let user = new User("John");
user.sayHi();
new User("John") çaÄırıldıÄında:
- Yeni bir nesne oluÅturuluyor.
constructorverilen argümanla çalıÅıyor ve bunathis.nameâi atıyor.
â¦Daha sonra user.sayHi gibi metodları çaÄırabiliriz.
Acemi geliÅtiricilerin düÅtüÄü bir hata da, sınıf metodları arasına virgül koymak. Bu da sözdimizi hatasına neden oluyor.
Buradaki notasyon nesne sabitleriyle karıÅtırılmamalı. Sınıf içinde virgüle ihtiyaç yok.
Sınıf nedir?
Peki, class (sınıf) tam olarak nedir? Bu aslında tam olarak yeni bir dil seviyesi obje deÄil.
Hadi, sihri ortaya çıkaralım ve bir sınıfın tam olarak ne olduÄunu görelim. Bu daha karmaÅık konseptleri anlamamıza da yardımcı olacak.
Javascriptâde sınıf aslında bir tür fonksiyondur.
Åuna bir göz atalım:
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// proof: User is a function
alert(typeof User); // function
class User {...} yapısının yaptıÄı Åey aslında:
Useradında, sınıfın tanımlayıcısın sonucu olacak, yeni bir fonksiyon oluÅturur.- The function code is taken from the
constructormethod (assumed empty if we donât write such method).
- The function code is taken from the
- Stores all methods, such as
sayHi, inUser.prototype.
Afterwards, for new objects, when we call a method, itâs taken from the prototype, just as described in the chapter F.prototype. So new User object has access to class methods.
We can illustrate the result of class User declaration as:
Hereâs the code to introspect it:
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// class is a function
alert(typeof User); // function
// ...or, more precisely, the constructor method
alert(User === User.prototype.constructor); // true
// The methods are in User.prototype, e.g:
alert(User.prototype.sayHi); // alert(this.name);
// there are exactly two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
Not just a syntax sugar
Sometimes people say that class is a âsyntax sugarâ in JavaScript, because we could actually declare the same without class keyword at all:
// rewriting class User in pure functions
// 1. Create constructor function
function User(name) {
this.name = name;
}
// any function prototype has constructor property by default,
// so we don't need to create it
// 2. Add the method to prototype
User.prototype.sayHi = function() {
alert(this.name);
};
// Usage:
let user = new User("John");
user.sayHi();
The result of this definition is about the same. So, there are indeed reasons why class can be considered a syntax sugar to define a constructor together with its prototype methods.
Although, there are important differences.
-
First, a function created by
classis labelled by a special internal property[[FunctionKind]]:"classConstructor". So itâs not entirely the same as creating it manually.Unlike a regular function, a class constructor canât be called without
new:class User { constructor() {} } alert(typeof User); // function User(); // Error: Class constructor User cannot be invoked without 'new'Also, a string representation of a class constructor in most JavaScript engines starts with the âclassâ¦â
class User { constructor() {} } alert(User); // class User { ... } -
Class methods are non-enumerable. A class definition sets
enumerableflag tofalsefor all methods in the"prototype".Thatâs good, because if we
for..inover an object, we usually donât want its class methods. -
Classes always
use strict. All code inside the class construct is automatically in strict mode.
Also, in addition to its basic operation, the class syntax brings many other features with it which weâll explore later.
Class Expression
Just like functions, classes can be defined inside another expression, passed around, returned, assigned etc.
Hereâs an example of a class expression:
let User = class {
sayHi() {
alert("Hello");
}
};
Similar to Named Function Expressions, class expressions may or may not have a name.
If a class expression has a name, itâs visible inside the class only:
// "Named Class Expression"
// (no such term in the spec, but that's similar to Named Function Expression)
let User = class MyClass {
sayHi() {
alert(MyClass); // MyClass is visible only inside the class
}
};
new User().sayHi(); // works, shows MyClass definition
alert(MyClass); // error, MyClass not visible outside of the class
We can even make classes dynamically âon-demandâ, like this:
function makeClass(phrase) {
// declare a class and return it
return class {
sayHi() {
alert(phrase);
};
};
}
// Create a new class
let User = makeClass("Hello");
new User().sayHi(); // Hello
Getters/setters, other shorthands
Just like literal objects, classes may include getters/setters, generators, computed properties etc.
Hereâs an example for user.name implemented using get/set:
class User {
constructor(name) {
// invokes the setter
this.name = name;
}
get name() {
return this._name;
}
set name(value) {
if (value.length < 4) {
alert("Name is too short.");
return;
}
this._name = value;
}
}
let user = new User("John");
alert(user.name); // John
user = new User(""); // Name too short.
The class declaration creates getters and setters in User.prototype, like this:
Object.defineProperties(User.prototype, {
name: {
get() {
return this._name
},
set(name) {
// ...
}
}
});
Hereâs an example with computed properties:
function f() { return "sayHi"; }
class User {
[f()]() {
alert("Hello");
}
}
new User().sayHi();
For a generator method, similarly, prepend it with *.
Class properties
Class-level properties are a recent addition to the language.
In the example above, User only had methods. Letâs add a property:
class User {
name = "Anonymous";
sayHi() {
alert(`Hello, ${this.name}!`);
}
}
new User().sayHi();
The property is not placed into User.prototype. Instead, it is created by new, separately for every object. So, the property will never be shared between different objects of the same class.
Summary
The basic class syntax looks like this:
class MyClass {
prop = value; // field
constructor(...) { // constructor
// ...
}
method(...) {} // method
get something(...) {} // getter method
set something(...) {} // setter method
[Symbol.iterator]() {} // method with computed name/symbol name
// ...
}
MyClass is technically a function (the one that we provide as constructor), while methods, getters and settors are written to MyClass.prototype.
In the next chapters weâll learn more about classes, including inheritance and other features.
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)