JavaScript Object (物件)
JavaScript 物件 (object) 是一個複合資料型態 (composite data type),可以儲存不定數量的鍵值對 (key-value pairs),而一組鍵值對我們稱做物件的一個屬性 (property)。一個屬性的值 (value) 可以是任何資料型態 (也可以是函數);而屬性的名稱 (key / name) 是一個字串型態。
物件宣告 (Creating Objects)
有兩種方式可以建立一個物件:
Object Constructor (物件建構式)
用 new 關鍵字加上 Object() 來宣告一個物件:
const myObj = new Object();
Object Literal (物件實字)
Object literal 是最常用也最方便的語法,用 {} 就可以宣告一個物件:
const myObj = {};
物件的屬性 (Object Properties)
存取屬性 (Accessing Properties)
我們可以用 . (Dot notation) 或 [] (Bracket notation) 來存取屬性。
- Dot notation (
.):最常用,語法簡潔。 - Bracket notation (
[]):當屬性名稱包含特殊符號、空格,或是動態變數時使用。
const myObj = {
color: 'blue',
'user name': 'Mike', // 包含空格的屬性名稱
};
// Dot notation
console.log(myObj.color); // 'blue'
// Bracket notation
console.log(myObj['color']); // 'blue'
console.log(myObj['user name']); // 'Mike'
// 動態存取
const propName = 'color';
console.log(myObj[propName]); // 'blue'
刪除屬性 (Deleting Properties)
使用 delete 關鍵字可以刪除物件的特定屬性。
const person = { name: 'Mike', age: 30 };
delete person.age;
console.log(person); // { name: 'Mike' }
檢查屬性是否存在
要檢查一個屬性是否存在於物件中,可以使用 in 運算子或 Object.hasOwn()(推薦,比 hasOwnProperty 更安全)。
const person = { name: 'Mike' };
console.log('name' in person); // true
console.log('age' in person); // false
// 現代寫法 (ES2022)
console.log(Object.hasOwn(person, 'name')); // true
Optional Chaining (可選串連) ?.
在存取深層巢狀物件時,為了避免 Uncaught TypeError: Cannot read properties of undefined 錯誤,我們可以使用 ?.。如果屬性不存在,它會短路並回傳 undefined,而不會報錯。
const user = {
name: 'Mike',
// address 屬性不存在
};
// 舊式寫法
const city = user.address ? user.address.city : undefined;
// 現代寫法
const city2 = user?.address?.city; // undefined (不會報錯) // 變數名稱改為 city2 避免重複宣告
物件的方法 (Object Methods)
物件的屬性值如果是一個函數,我們稱它是物件的方法 (method)。
const person = {
firstName: 'Mike',
lastName: 'Lee',
// 使用 this 關鍵字存取物件本身的屬性
fullName: function () {
return this.firstName + ' ' + this.lastName;
},
};
console.log(person.fullName()); // "Mike Lee"
ES6 Object Literal Extensions (新語法)
ES6 提供了讓物件寫法更簡潔的語法糖。
1. 屬性簡寫 (Property Shorthand)
當屬性名稱與變數名稱相同時,可以省略冒號與值。
const name = 'Mike';
const age = 30;
// 舊寫法
const person1 = { name: name, age: age };
// 新寫法
const person2 = { name, age };
2. 方法簡寫 (Method Shorthand)
定義方法時,可以省略 function 關鍵字。
const person = {
name: 'Mike',
// 舊寫法
sayHello: function () {
console.log('Hello!');
},
// 新寫法
sayHi() {
console.log('Hi!');
},
};
3. 計算屬性名稱 (Computed Property Names)
允許使用表達式 [] 來動態產生屬性名稱。
const prefix = 'user';
const id = 123;
const user = {
[prefix + '_' + id]: 'Mike', // 屬性名稱變為 "user_123"
};
console.log(user.user_123); // "Mike"
物件的遍歷與操作 (Looping & Manipulation)
遍歷物件
for...in迴圈:遍歷所有可枚舉屬性(包含繼承的)。Object.keys():回傳所有 Key 的陣列。Object.values():回傳所有 Value 的陣列。Object.entries():回傳[Key, Value]的陣列。
const person = { name: 'Mike', age: 30 };
// Object.keys
Object.keys(person).forEach((key) => {
console.log(key, person[key]);
});
// 輸出:
// name Mike
// age 30
合併與複製 (Merging & Cloning)
在現代 JavaScript 中,我們通常使用 Spread Operator (...) 進行淺拷貝 (Shallow Copy) 或合併。
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
// 合併物件 (後面的屬性會覆蓋前面的)
const merged = { ...obj1, ...obj2 };
// { a: 1, b: 3, c: 4 }
// 複製物件
const clone = { ...obj1 };
注意:Spread Operator 只是「淺拷貝」。如果物件內還有巢狀物件,巢狀物件仍然是 reference 參考,修改它會影響到原始物件。
JavaScript 內建物件
JavaScript 還有許多特殊的內建物件: