Javascript classes
Bài đăng này đã không được cập nhật trong 7 năm
Javascript classes được giới thiệu trong ECMAScript 2015 (ES6). Các lớp JavaScript cung cấp một cú pháp đơn giản hơn và rõ ràng hơn để tạo các đối tượng và làm việc với sự thừa kế.
Định nghĩa class
Các class thực chất là "các hàm đặc biệt", và cũng giống như bạn có thể định nghĩa hàm và khai báo hàm, cú pháp class cũng có định nghĩa biểu thức lớp (class expressions) và khai báo lớp (class declarations).
Class declarations
Sử dụng từ khóa class để định nghĩa một class mới
class HinhChuNhat {
constructor(chieuDai, chieuRong) {
this.chieuDai = chieuDai;
this.chieuRong = chieuRong;
}
}
Class expressions
Một cách khác để định nghĩa class là sử dụng biểu thức. Biểu thức lớp có thể được đăt tên hoặc không.
// không đặt tên
let HinhChuNhat = class {
constructor(chieuDai, chieuRong) {
this.chieuDai = chieuDai;
this.chieuRong = chieuRong;
}
};
// đặt tên
let HinhChuNhat = class HinhChuNhat {
constructor(chieuDai, chieuRong) {
this.chieuDai = chieuDai;
this.chieuRong = chieuRong;
}
};
Định nghĩa thân Class và các method
Thân class được đặt trong cặp dấu ngoặc nhọn {}
Constructor
Method constructor
là phương thức đặc biệt để tạo và khởi tạo một đối tượng được tạo ra bởi một lớp. Chỉ có thể có một phương thức constructor
trong một lớp, nhiều hơn sẽ gây ra lỗi. Trong method constructor
có thể sử dụng từ khóa super
để gọi constructor
của lớp cha.
Prototype methods
Định nghĩa các phuong thức bên trong class
class HinhChuNhat {
constructor(chieuDai, chieuRong) {
this.chieuDai = chieuDai;
this.chieuRong = chieuRong;
}
// Getter
get dienTich() {
return this.tinhDienTich();
}
// Method
tinhDienTich() {
return this.chieuDai * this.chieuRong;
}
}
const hinhVuong = new HinhChuNhat(10, 10);
console.log(hinhVuong.dienTich); // 100
Static methods
Các phương thức static
chỉ có thể được gọi "tĩnh", không thể gọi thông qua một instance của class.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
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);
console.log(Point.distance(p1, p2)); // 7.0710678118654755
console.log(p1.distance()); // TypeError: p1.distance is not a function
Boxing with prototype and static methods
Khi prototype methods hoặc static methods được gọi trong bối cảnh không có giá trị this
thì từ khóa this
sẽ trả về undefined
bên trong function được gọi. Trừu tượng quá nhỉ, xem ví dụ thôi nào:
class Animal {
speak() {
return this;
}
static eat() {
return this;
}
}
let obj = new Animal();
obj.speak(); // Animal {}
let speak = obj.speak;
speak(); // undefined
Animal.eat() // class Animal
let eat = Animal.eat;
eat(); // undefined
Viết lại theo cách khác xem kết quả thế nào nhé, ví dụ dưới đây có xảy ra autoboxing
function Animal() { }
Animal.prototype.speak = function() {
return this;
}
Animal.eat = function() {
return this;
}
let obj = new Animal();
let speak = obj.speak;
speak(); // global object
let eat = Animal.eat;
eat(); // global object
Kế thừa với từ khóa extends
CŨng giống như nhiều ngôn ngữ lập trình khác, chúng ta có thể tạo ra một class mới kế thừa từ class cha bằng từ khóa extends
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' gây ra tiếng ồn.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' sủa gâu gâu.');
}
}
var d = new Dog('Mitzie');
d.speak(); // Mitzie sủa gâu gâu.
Nếu có method constructor
trong lớp con thì nó phải gọi super
trước khi sử dụng được từ khóa this
Chú ý rằng một class không thể kế thừa từ một object bình thường. Nếu muốn làm điều này, thì bạn có thể dùng Object.setPrototypeOf()
:
var Animal = {
speak() {
console.log(this.name + ' gây ra tiếng ồn.');
}
};
class Dog {
constructor(name) {
this.name = name;
}
}
Object.setPrototypeOf(Dog.prototype, Animal);// If you do not do this you will get a TypeError when you invoke speak
var d = new Dog('Mitzie');
d.speak(); // Mitzie gây ra tiếng ồn.
Gọi method trong class cha với từ khóa super
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' gây ra tiếng ồn.');
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(this.name + gầm...');
}
}
var l = new Lion('Fuzzy');
l.speak();
// Fuzzy gây ra tiếng ồn.
// Fuzzy gầm...
All rights reserved