By GokiSoft.Com| 22:01 18/05/2020|
Tài Liệu Javascript

JavaScript Classes

ECMAScript 2015


ES6, cũng được biết với tên ECMAScript2015, giới thiệu về các class.

Một class là một kiểu của hàm, nhưng thay vì sử dụng từ khóa  function để khởi tạo nó, chúng ta dùng từ khóa  class,và các thuộc tính được gán bên trong một phương thức  constructor().



Định nghĩa Class(Class Definition)


Sử dụng  class để tạo một class, và luôn luôn thêm phương thức  constructor() .

Phương thức constructor được gọi mỗi lần đối tượng class được khởi tạo.

ví dụ

Một định nghĩa class đơn giản cho một class tên là "Car":

class Car {
  constructor(brand) {
    this.carname = brand;
  }
}


Bây giờ bạn có thể tạo các đối tượng sử dụng class Car:

ví dụ

Tạo một đối tượng tên là "mycar" dựa trên lớp Car:

class Car {
  constructor(brand) {
    this.carname = brand;
  }
}
mycar = new Car("Ford");
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class</h2>

<p>In this example we demonstrate a simple class definition and how to use it.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this.carname = brand;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = mycar.carname;
</script>

</body>
</html>


Ghi chú: Phương thức constructor được gọi tự động, khi đối tượng được khởi tạo.



Các phương thức(Methods)


Phương thức constructor khá đặc biệt, nó giống như khi bạn khởi tạo các thuộc tính, nó được gọi tự động khi một class được khởi tạo, và nó phải có tên chính xác "constructor", trong thực tế, nếu bạn không có một phương thức constructor, JavaScript sẽ thêm một phương thức constructor không thể nhìn thấy và rỗng.

ví dụ

Tạo một phương thức tên "present":

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  present() {
    return "I have a " + this.carname;
  }
}

mycar = new Car("Ford");
document.getElementById("demo").innerHTML = mycar.present();
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class Method</h2>

<p>Demonstration of how to add a method in a JavaScript Class.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this.carname = brand;
  }
  present() {
    return "I have a " + this.carname;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = mycar.present();
</script>

</body>
</html>


Như bạn đã thấy trong ví dụ trên, bạn gọi phương thức bằng cách liên hệ nó với tên phương thức của đối tượng, theo sau là dấu ngoặc đơn (mọi tham số sẽ ở bên trong dấu ngoặc đơn).

ví dụ

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  present(x) {
    return x + ", I have a " + this.carname;
  }
}

mycar = new Car("Ford");
document.getElementById("demo").innerHTML = mycar.present("Hello");
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class Method</h2>

<p>Pass a parameter into the "present()" method.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this.carname = brand;
  }
  present(x) {
    return x + ", I have a " + this.carname;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = mycar.present("Hello");
</script>

</body>
</html>



Các phương thức tĩnh(Static Methods)


Các phương thức tĩnh được định nghĩa trong class chính nó, và không phải trên mẫu gốc.

Nghĩa là bạn không thể gọi một phương thưc trong đối tượng (mycar), mà chỉ có thể gọi trên class (Car):

ví dụ

Tạo một phương thức tĩnh và gọi nó trên class:

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  static hello() {
    return "Hello!!";
  }
}

mycar = new Car("Ford");

//Call 'hello()' on the class Car:
document.getElementById("demo").innerHTML = Car.hello();

//and NOT on the 'mycar' object:
//document.getElementById("demo").innerHTML = mycar.hello();
//this would raise an error.
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class Static Methods</h2>

<p>A static method is created with the "static" keyword, and you can only call the method on the class itself.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this.carname = brand;
  }
  static hello() {
    return "Hello!!";
  }
}

mycar = new Car("Ford");

//Call 'hello()' on the class Car:
document.getElementById("demo").innerHTML = Car.hello();

//and NOT on the 'mycar' object:
//document.getElementById("demo").innerHTML = mycar.hello();
//this would raise an error.
</script>

</body>
</html>

Nếu bạn muốn sử dụng đối tượng mycar bên trong phương thức tĩnh, bạn có thể gửi nó như một tham số:

ví dụ

Gửi "mycar" như một tham số:

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  static hello(x) {
    return "Hello " + x.carname;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = Car.hello(mycar);
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class Static Methods</h2>

<p>To use the "mycar" object inside the static method, you can send it as parameter.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this.carname = brand;
  }
  static hello(x) {
    return "Hello " + x.carname;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = Car.hello(mycar);
</script>

</body>
</html>



Thừa kế(Inheritance)


Để tạo một class thừa kế, dùng từ khóa  extends.

Một class được tạo với một class thừa kế, kế thừa toàn bộ các phương thức từ class khác:

ví dụ

Tạo một class tên "Model" mà nó sẽ kế thừa các phương thức từ class "Car":

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  present() {
    return 'I have a ' + this.carname;
  }
}

class Model extends Car {
  constructor(brand, mod) {
    super(brand);
    this.model = mod;
  }
  show() {
    return this.present() + ', it is a ' + this.model;
  }
}

mycar = new Model("Ford", "Mustang");
document.getElementById("demo").innerHTML = mycar.show();
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class Inheritance</h2>

<p>Use the "extends" keyword to inherit all methods from another class.</p>
<p>Use the "super" method to call the parent's constructor function.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this.carname = brand;
  }
  present() {
    return 'I have a ' + this.carname;
  }
}

class Model extends Car {
  constructor(brand, mod) {
    super(brand);
    this.model = mod;
  }
  show() {
    return this.present() + ', it is a ' + this.model;
  }
}

mycar = new Model("Ford", "Mustang");
document.getElementById("demo").innerHTML = mycar.show();
</script>

</body>
</html>


Phương thức super() liên kết đến class cha.

Bằng cách gọi phương thức super() trong phương thức constructor, chúng ta gọi phương thức constructor cha và truy cập vào các thuộc tính và phương thức của class cha.

Thừa kế hữu dụng cho việc tái sử dụng code: tái sử dụng các thuộc tính và các phương thức của một class đang tồn tại khi bạn tạo một class mới.



Các Getter và Setter


Các class cũng cho phép bạn sử dụng các getter và setter.

Bạn có thể dùng các getter và setter một cách thông minh cho các thuộc tính của bạn, cụ thể nếu bạn muốn làm gì đó đặc biệt với giá trị trước khi trả về chúng hoặc trước khi bạn đặt chúng.


Để thêm các getter và setter trong class, dùng từ khóa get và set.

ví dụ

Tạo một getter và một setter cho thuộc tính "carname":

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  get cnam() {
    return this.carname;
  }
  set cnam(x) {
    this.carname = x;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = mycar.cnam;
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class Gettter/Setter</h2>

<p>A demonstration of how to add getters and setters in a class, and how to use the getter to get the property value.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this.carname = brand;
  }
  get cnam() {
    return this.carname;
  }
  set cnam(x) {
    this.carname = x;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = mycar.cnam;
</script>

</body>
</html>


Ghi chú: Kể cả khi nếu getter là một phương thức, bạn không được sử dụng các dấu ngoặc đơn khi bạn muốn lấy giá trị thuộc tính.

Tên của phương thức getter/setter không thể giống với tên của thuộc tính, trong trường hợp này là carname.

ví dụ

Bạn có thể dùng dấu gạch dưới để tách các getter/setter khỏi thuộc tính thật:

class Car {
  constructor(brand) {
    this._carname = brand;
  }
  get carname() {
    return this._carname;
  }
  set carname(x) {
    this._carname = x;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = mycar.carname
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class Gettter/Setter</h2>

<p>Using an underscore character is common practice when using getters/setters in JavaScript, but not mandatory, you can name them anything you like, but not the same as the property name.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this._carname = brand;
  }
  get carname() {
    return this._carname;
  }
  set carname(x) {
    this._carname = x;
  }
}

mycar = new Car("Ford");

document.getElementById("demo").innerHTML = mycar.carname;
</script>

</body>
</html>


Để dùng một setter, sử dụng cùng cú pháp như khi bạn đặt một giá trị thuộc tính, không có các dấu ngoặc đơn:

ví dụ

Sử dụng setter để thay đổi carname thành "Volvo":

class Car {
  constructor(brand) {
    this._carname = brand;
  }
  get carname() {
    return this._carname;
  }
  set carname(x) {
    this._carname = x;
  }
}

mycar = new Car("Ford");
mycar.carname = "Volvo";
document.getElementById("demo").innerHTML = mycar.carname;
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Class Setter</h2>

<p>When using a setter to set a property value, you do not use parantheses.</p>

<p id="demo"></p>

<script>
class Car {
  constructor(brand) {
    this._carname = brand;
  }
  set carname(x) {
    this._carname = x;
  }
  get carname() {
    return this._carname;
  }
}

mycar = new Car("Ford");
mycar.carname = "Volvo";
document.getElementById("demo").innerHTML = mycar.carname;
</script>

</body>
</html>



Hoisting


Khác với các hàm, và các khai báo JavaScript khác, khai báo class không được nâng lên.

Nghĩa là bạn phải khai báo class trước khi bạn dùng nó:

ví dụ

//You cannot use the class yet.
//mycar = new Car("Ford")
//This would raise an error.

class Car {
  constructor(brand) {
    this.carname = brand;
  }
}

//Now you can use the class:
mycar = new Car("Ford")
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Classes are not hoisted</h2>

<p>You will get an error if you try to use a class before it is declared.</p>

<p id="demo"></p>

<script>
//You cannot use the class yet.
//mycar = new Car("Ford")
//This would raise an error.

class Car {
  constructor(brand) {
    this.carname = brand;
  }
}

//Now you can use the class:
mycar = new Car("Ford")
</script>

</body>
</html>


Ghi chú: Với các khai báo khác, như các hàm, bạn sẽ KHÔNG nhận được một lỗi khi bạn cố gắng sử dụng nó trước khi nó được khai báo, bởi vì hành động mặc định của khai báo JavaScript là hoisting (chuyển các khai báo lên trên đầu).



"Sử dụng chế độ nghiêm ngặt(use strict)"


Cú pháp trong các class phải được viết trong "chế độ nghiêm ngặt".

Bạn sẽ nhận được một lỗi nếu bạn không tuân theo các quy tắc của "chế độ nghiêm ngặt".

ví dụ

Trong "chế độ nghiêm ngặt" bạn sẽ nhận được một lỗi nếu bạn dùng biến mà không khai báo nó:

class Car {
  constructor(brand) {
    i = 0;
    this.carname = brand;
  }
}
var mycar = new Car("Ford");
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Classes are written in "strict mode"</h2>

<p>You will get an error if you try to use a variable without declaring it.</p>

<script>
class Car {
  constructor(brand) {
    i = 0;
    this.carname = brand;
  }
}
var mycar = new Car("Ford");
</script>

<p>Press F12 to see the error description in the console.</p>

</body>
</html>


Học nhiều hơn về "chế độ nghiêm ngặt" trong chương chế độ nghiêm ngặt trong JavaScript Strict Mode.



Hỗ trợ trình duyệt


Bảng sau xác định các phiên bản trình duyệt đầu tiên với hỗ trợ đầy đủ cho các Class trong JavaScript: