一、簡介
建構函數是 JavaScript 中用來創建和初始化物件的一種特殊函數。
它像一個「模具」,透過new 關鍵字生成多個相似的物件實例。特點
- 函數名稱通常首字母大寫(慣例,非強制)。
- 使用
new呼叫時,自動創建新物件並設定this。new會在記憶體的堆中分配空間給新物件,每次創建的實例都獨立,佔用不同的記憶體位置。 - 可以定義屬性和方法。
二、基本運作
1.定義建構函數
function Person(name, age) {
this.name = name; // 屬性
this.age = age;
this.sayHi = function() { // 方法
console.log(`Hi, I'm ${this.name}`);
};
}
2.使用 new 創建實例
const person1 = new Person("Alice", 25);
const person2 = new Person("Bob", 30);
console.log(person1.name); // "Alice"
person1.sayHi(); // "Hi, I'm Alice"
console.log(person2.age); // 30
new 做了什麼?
- 創建一個空物件
{},並在記憶體中分配獨立空間。 - 將
this綁定到這個新物件。 - 執行建構函數內的程式碼,設置屬性和方法。
- 自動返回這個新物件(除非手動返回其他東西)。
- 創建一個空物件
實例獨立性:
每個用 new 創建的實例(例如 person1 和 person2)是獨立的,佔用不同的記憶體位置,互不影響。可以用 person1 === person2 驗證,結果會為 false)。
三、建構函數的執行過程
function Car(model) {
this.model = model;
this.drive = function() {
console.log(`Driving a ${this.model}`);
};
}
const myCar = new Car("Toyota");
myCar.drive(); // "Driving a Toyota"
步驟:
- 1.
new Car("Toyota"):- 創建空物件
{},分配獨立記憶體空間。 this指向這個物件。
- 創建空物件
- 2.執行函數:
this.model = "Toyota"this.drive = function...
- 3.返回物件:
myCar得到{ model: "Toyota", drive: function },獨立於其他實例。
四、建構函數與 class 的關係
ES6 引入 class,其實是建構函數的語法糖。
// 建構函數
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
console.log(`Hi, I'm ${this.name}`);
};
// Class 寫法
class PersonClass {
constructor(name) {
this.name = name;
}
sayHi() {
console.log(`Hi, I'm ${this.name}`);
}
}
const p1 = new Person("Alice");
const p2 = new PersonClass("Bob");
p1.sayHi(); // "Hi, I'm Alice"
p2.sayHi(); // "Hi, I'm Bob"
差異:
class是更高階的抽象,內部仍基於原型。class更直觀,方法自動綁到原型。
五、注意事項
1.忘記 new
如果直接呼叫 Person("Alice")(不加 new),this 會指向全域物件(瀏覽器中是 window),造成錯誤。
function Person(name) {
this.name = name;
}
Person("Alice"); // 無 new
console.log(window.name); // "Alice"(全域污染)
解法:嚴格模式("use strict")會報錯,或檢查 this:
//嚴格模式
"use strict";
function Person(name) {
this.name = name;
}
Person("Alice"); // 報錯:Cannot set property 'name' of undefined
//檢查 this
function Person(name) {
if (!(this instanceof Person)) {
return new Person(name);
}
this.name = name;
}
const p = Person("Alice"); // 即使忘了 new 也沒問題
console.log(p.name); // "Alice"
2. 返回值的影響
正常情況下,new 會返回建構函數創建的物件(this)。但如果建構函數明確返回一個物件(而不是 undefined 或基本類型),new 會返回這個手動指定的物件,忽略 this。
function Test() {
this.name = "Test";
return { name: "Override" }; // 手動返回物件
}
const t = new Test();
console.log(t.name); // "Override"(而非 "Test")
//對比:
function Test2() {
this.name = "Test";
return "string"; // 返回基本類型
}
const t2 = new Test2();
console.log(t2.name); // "Test"(基本類型被忽略,new 使用 this)














