Hai cách thiết lập prototype chain khác biệt về việc có gọi constructor của class cha hay không.
1. Object.create(Parent.prototype)
function SomeClass() {}
SomeClass.prototype = Object.create(Parent.prototype);
- Tạo object mới với
[[Prototype]]trỏ đếnParent.prototype. - Không gọi constructor
Parent. - Instance của
SomeClass không có own properties từParentconstructor. - Phù hợp khi
Parentkhông cần khởi tạo state (stateless) hoặc chỉ dùng prototype methods.
2. new Parent()
function SomeClass() {}
SomeClass.prototype = new Parent();
- Tạo instance thực sự của
Parent. - Gọi constructor
Parent– có thể tạo own properties, side effects. - Prototype chain:
SomeClass.prototype → Parent instance → Parent.prototype → Object.prototype. - Rủi ro: properties trên instance cha trở thành shared state cho tất cả con (nếu là object/array).
So sánh
| Đặc điểm | Object.create(Parent.prototype) | new Parent() |
|---|---|---|
| Gọi constructor cha | Không | Có |
| Own properties từ cha | Không có | Có (shared!) |
| Side effects cha | Không | Có |
| constructor property | Cần sửa thủ công | Tự động đúng (nhưng trỏ về Parent) |
| Khuyến nghị | Hiện đại, an toàn | Legacy, rủi ro shared state |
Best practice hiện đại (ES6+)
class Parent { constructor() { this.id = 1; } }
class Child extends Parent {
constructor() {
super(); // Bắt buộc gọi super() trước khi dùng this
this.childProp = 2;
}
}
extends + super() xử lý prototype chain và constructor call đúng chuẩn.