物件(Object)
什麼是物件?
比喻:物件就像一張個人名片 📇
名片上有:姓名、電話、公司、職位... 物件就是用「屬性名:值」的方式組織資料。
建立物件
// 物件字面值
let person = {
name: "小明", // ← 屬性名: 值
age: 20,
email: "ming@test.com",
isStudent: true,
hobbies: ["籃球", "吉他"], // ← 值可以是陣列
address: { // ← 值可以是另一個物件
city: "台北",
district: "信義區"
}
};
存取屬性
// 點記法
console.log(person.name); // ← "小明"
console.log(person.address.city); // ← "台北"
// 括號記法(屬性名是變數或含特殊字元時用)
console.log(person["name"]); // ← "小明"
let key = "age";
console.log(person[key]); // ← 20(用變數當 key)
// 修改
person.age = 21;
person["email"] = "new@test.com";
// 新增
person.phone = "0912345678";
// 刪除
delete person.phone;
物件方法
let calculator = {
value: 0,
// 方法(ES6 簡寫)
add(n) {
this.value += n; // ← this 指向這個物件自己
return this; // ← 回傳自己,可以鏈式呼叫
},
subtract(n) {
this.value -= n;
return this;
},
getResult() {
return this.value;
}
};
let result = calculator.add(10).subtract(3).add(5).getResult();
console.log(result); // ← 12
解構賦值
let { name, age, email = "無" } = person;
// 等同於:
// let name = person.name;
// let age = person.age;
// let email = person.email ?? "無";
console.log(name); // ← "小明"
// 重新命名
let { name: userName, age: userAge } = person;
console.log(userName); // ← "小明"
// 巢狀解構
let { address: { city } } = person;
console.log(city); // ← "台北"
展開運算子
// 複製物件(淺拷貝)
let copy = { ...person };
// 合併物件
let defaults = { theme: "dark", lang: "zh" };
let userPrefs = { lang: "en" };
let settings = { ...defaults, ...userPrefs };
// ← { theme: "dark", lang: "en" }(後面的覆蓋前面的)
常用靜態方法
let obj = { a: 1, b: 2, c: 3 };
// Object.keys — 取所有 key
Object.keys(obj); // ← ["a", "b", "c"]
// Object.values — 取所有 value
Object.values(obj); // ← [1, 2, 3]
// Object.entries — 取 [key, value] 配對
Object.entries(obj); // ← [["a",1], ["b",2], ["c",3]]
// 搭配 for...of
for (let [key, value] of Object.entries(obj)) {
console.log(`${key}: ${value}`);
}
// Object.assign — 合併(會修改第一個參數)
let target = { a: 1 };
Object.assign(target, { b: 2 }, { c: 3 });
console.log(target); // ← { a: 1, b: 2, c: 3 }
// Object.freeze — 凍結(不能改)
let frozen = Object.freeze({ x: 1, y: 2 });
frozen.x = 99; // ← 靜默失敗(嚴格模式下會報錯)
console.log(frozen.x); // ← 1(沒有改到)
Optional Chaining(?.)
let user = {
name: "小明",
address: null
};
// 沒有 ?. 會報錯
// console.log(user.address.city); // ❌ TypeError!
// 有 ?. 安全存取
console.log(user.address?.city); // ← undefined(不報錯)
console.log(user.profile?.avatar); // ← undefined
// 搭配方法呼叫
user.greet?.(); // ← 如果 greet 方法存在才呼叫