Constructor Function là hàm thông thường được gọi với từ khóa new để tạo instance. Theo convention: tên hàm viết **PascalCase**.
Quy trình khi gọi new Constructor():
- Tạo object rỗng
{}gán chothis - Link
this.__proto__=Constructor.prototype - Thực thi body hàm (gán property vào
this) - Tự động trả về
this(trừ khi return object khác)
Ví dụ minh họa
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Constructor với new</title>
<style>
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
.result { font-size: 18px; font-weight: 500; margin: 10px 0; color: green; }
button { padding: 8px 16px; cursor: pointer; }
</style>
</head>
<body>
<h1>JavaScript Constructor với từ khóa new</h1>
<div class="result" id="result"></div>
<button class="Btn" id="btn">NHẤN VÀO ĐÂY</button>
<h3> Nhấn nút để tạo instance từ Constructor </h3>
<script>
const resEle = document.querySelector("#result");
// Constructor Function (PascalCase)
function Human(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
// Không cần return this (tự động)
}
// Tạo instance
const obj = new Human('Rohan', 'Sharma', 22);
document.querySelector("#btn").addEventListener("click", () => {
for (const key in obj) {
resEle.innerHTML += `Key = ${key} : Value = ${obj[key]}
`;
}
resEle.innerHTML += `
obj instanceof Human: ${obj instanceof Human}`; // true
resEle.innerHTML += `
obj.constructor === Human: ${obj.constructor === Human}`; // true
resEle.innerHTML += `
Object.getPrototypeOf(obj) === Human.prototype: ${Object.getPrototypeOf(obj) === Human.prototype}`;
});
</script>
</body>
</html>
Kết quả
Key = firstName : Value = Rohan Key = lastName : Value = Sharma Key = age : Value = 22 obj instanceof Human: true obj.constructor === Human: true Object.getPrototypeOf(obj) === Human.prototype: true
Quên new sẽ sao?
function Human(name) { this.name = name; }
const a = new Human("Alice"); // OK: this = instance mới
const b = Human("Bob"); // ❌ this = window (non-strict) hoặc undefined (strict)
// b = undefined, window.name = "Bob" (leak global!)
Bảo vệ khỏi quên new (New.target - ES2015):
function Human(name) {
if (!new.target) {
// Được gọi không có new
return new Human(name); // Tự động new
// Hoặc throw new Error("Phải dùng new");
}
this.name = name;
}
const a = new Human("Alice"); // OK
const b = Human("Bob"); // OK - tự động new
Prototype Methods (Shared methods):
function Human(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// Thêm method vào prototype (chia sẻ cho tất cả instances)
Human.prototype.getFullName = function() {
return `${this.firstName} ${this.lastName}`;
};
Human.prototype.greet = function() {
return `Xin chào, tôi là ${this.getFullName()}`;
};
const user = new Human("Rohan", "Sharma");
user.getFullName(); // "Rohan Sharma"
user.greet(); // "Xin chào, tôi là Rohan Sharma"
Class Syntax (ES6 - Syntactic Sugar):
class Human {
constructor(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
static species = "Homo sapiens"; // Static property
static createBaby(name) { // Static method
return new Human(name, "Unknown", 0);
}
}
const user = new Human("Rohan", "Sharma", 22);
// Tương đương constructor function nhưng syntax sạch hơn
So sánh Constructor Function vs Class:
| Đặc điểm | Constructor Function | Class (ES6) |
|---|---|---|
| Syntax | Function + prototype | Class keyword |
| Hoisting | Hoisted (function declaration) | Không hoisted (TDZ) |
| Strict mode | Tự chọn | Luôn strict mode |
| Methods | Gán vào prototype thủ công | Trong class body |
| Static | Constructor.prop = ... | static prop = ... |
| Extends | Manual prototype chain | extends, super() |