在 JavaScript 中,物件是一種非常常見的資料型別,幾乎每個程式設計師都會在日常工作中頻繁地使用物件。在本篇文章中,我們將深入瞭解 JavaScript 物件的一些基本概念和一些高階概念,這些概念對於我們正確理解物件在 JavaScript 中的行為非常重要。
在 JavaScript 中,物件是由鍵值對組成的集合。鍵是一個字串或者 Symbol 型別的值,值可以是任何型別的資料,包括其他物件。物件是一種動態資料結構,可以通過新增、刪除或修改屬性來改變物件的狀態。以下是 JavaScript 中定義物件的一些基本語法:
const myObj = {
key1: 'value1',
key2: 'value2',
key3: 'value3',
};
在這個物件中,每一個鍵都有一個相應的值。可以使用點操作符或方括號操作符來存取物件的屬性:
console.log(myObj.key1); // 輸出 'value1'
console.log(myObj['key2']); // 輸出 'value2'
可以通過以下方式向物件新增新的屬性:
myObj.newKey = 'newValue';
console.log(myObj.newKey); // 輸出 'newValue'
物件也可以作為函數的引數和返回值:
function createObj() {
return { key1: 'value1', key2: 'value2', key3: 'value3' };
}
const obj = createObj();
console.log(obj.key1); // 輸出 'value1'
在 JavaScript 中,物件之間可以有一種原型關係,即一個物件可以繼承另一個物件的屬性和方法。每一個物件都有一個原型物件,它是另一個物件的參照,可以通過 Object.getPrototypeOf(obj) 來存取。
在 JavaScript 中,有兩種方式來建立一個新物件:
建構函式可以使用 new 關鍵字來呼叫,它會建立一個新的物件並把這個物件的原型設定為建構函式的 prototype 屬性。
在後一種方式中,可以通過建構函式的 prototype 屬性來為新物件新增方法和屬性。新建立的物件會繼承建構函式的原型,因此可以存取這些方法和屬性。以下是一個簡單的例子:
function MyObj() {
this.name = 'My Object';
}
MyObj.prototype.getName = function () {
return this.name;
};
const obj = new MyObj();
console.log(obj.getName()); // 輸出 'My Object'
在 JavaScript 中,this 關鍵字指的是當前正在執行的函數的上下文物件。在物件中,this 指向該物件本身。例如:
const myObj = {
name: 'My Object',
getName: function () {
return this.name;
},
};
console.log(myObj.getName()); // 輸出 'My Object'
在JS中,物件是一種複合值,包含了無數個屬性(key-value pairs),它可以是字串、數位、布林值、陣列或者其他物件等等。物件是JS中最重要的資料結構之一。
最常見的建立物件的方法是使用物件字面量。物件字面量是一個由若干鍵值對組成的物件。這種方式建立的物件可以直接使用{}來表示,也可以使用一個變數來儲存這個物件。
const person = { name: 'Alice', age: 18, gender: 'female' };
物件字面量建立的物件可以直接在定義時新增屬性,也可以後期新增。
const person = {};
person.name = 'Alice';
person.age = 18;
person.gender = 'female';
除了物件字面量之外,還可以使用Object建構函式來建立物件。可以使用new關鍵字和Object建構函式建立一個空物件,或者將一個現有物件作為引數傳遞給Object建構函式來建立一個與該物件相同的新物件。
const emptyObj = new Object();
const person = new Object({ name: 'Alice', age: 18, gender: 'female' });
工廠函數是一個返回物件的函數。它們通過抽象化物件的建立和初始化來降低重複程式碼的量。當需要建立多個類似的物件時,可以使用工廠函數來代替每個物件都寫一遍相同的程式碼。
function createPerson(name, age, gender) {
return { name, age, gender };
}
const person1 = createPerson('Alice', 18, 'female');
const person2 = createPerson('Bob', 20, 'male');
建構函式是一種特殊的函數,用於建立並初始化一個由該型別定義的物件。當我們使用new關鍵字建立物件時,實際上是在呼叫建構函式。
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
const person1 = new Person('Alice', 18, 'female');
const person2 = new Person('Bob', 20, 'male');
ES6引入了class語法,讓JS的物件導向程式設計更加直觀和易於理解。使用class建立物件的語法如下:
class Person {
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
}
const person1 = new Person('Alice', 18, 'female');
const person2 = new Person('Bob', 20, 'male');
存取 JS 物件的屬性和方法通常有兩種方式:點語法和方括號語法。
使用點語法,可以通過物件名稱後面跟隨一個句點,然後是屬性名,來存取物件的屬性和方法,例如:
const obj = {
name: 'Alice',
age: 25,
sayHello() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
};
console.log(obj.name); // 輸出 'Alice'
console.log(obj.age); // 輸出 25
obj.sayHello(); // 輸出 'Hello, my name is Alice and I am 25 years old.'
使用方括號語法,可以通過物件名稱後面跟隨一個方括號,裡面是屬性名或者變數名,來存取物件的屬性和方法,例如:
const obj = {
name: 'Alice',
age: 25,
sayHello() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
};
console.log(obj['name']); // 輸出 'Alice'
console.log(obj['age']); // 輸出 25
obj['sayHello'](); // 輸出 'Hello, my name is Alice and I am 25 years old.'
使用方括號語法時,可以在方括號中使用表示式,例如:
const obj = {
name: 'Alice',
age: 25,
sayHello() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
};
const propName = 'name';
console.log(obj[propName]); // 輸出 'Alice'
const method = 'sayHello';
obj[method](); // 輸出 'Hello, my name is Alice and I am 25 years old.'
需要注意的是,在方括號語法中,屬性名或者變數名必須用引號括起來,否則會被解釋為變數名。另外,在使用方括號語法存取物件的屬性和方法時,可以使用變數名,這個變數名可以在執行時決定。
總的來說,存取 JS 物件的屬性和方法是非常簡單的,但是需要注意使用點語法和方括號語法的區別,以及在使用方括號語法時需要注意屬性名或者變數名的引號問題。
遍歷物件是很常見的操作。物件的遍歷可以使用 for-in 迴圈,也可以使用 Object.keys() 方法遍歷物件的鍵名。
const obj = { name: 'Tom', age: 18, gender: 'male' };
// 使用 for-in 迴圈遍歷物件
for (let key in obj) {
console.log(key, obj[key]);
}
// 使用 Object.keys() 方法遍歷物件的鍵名
Object.keys(obj).forEach(key => {
console.log(key, obj[key]);
});
Object.keys(), Object.values(), 和 Object.entries() 都是用於操作物件的方法。
下面我們舉個例子來說明這三個方法的使用:
const person = {
firstName: 'John',
lastName: 'Doe',
age: 30,
email: '[email protected]'
};
// Object.keys()
const keys = Object.keys(person);
console.log(keys); // ['firstName', 'lastName', 'age', 'email']
// Object.values()
const values = Object.values(person);
console.log(values); // ['John', 'Doe', 30, '[email protected]']
// Object.entries()
const entries = Object.entries(person);
console.log(entries); // [['firstName', 'John'], ['lastName', 'Doe'], ['age', 30], ['email', '[email protected]']]
通過這三個方法,我們可以方便地操作物件,快速獲取物件的屬性、屬性值以及屬性和屬性值的鍵值對。
小技巧可以通過Object.entries()方便的將物件轉為Map型別。
在 JavaScript 中,物件的賦值是淺拷貝,即只會拷貝物件的參照。如果需要實現物件的深拷貝,則需要使用一些特殊的方法。
淺拷貝只是將物件的參照拷貝給了另一個物件,因此在修改原物件時,拷貝物件也會發生變化。
const obj1 = { name: 'Tom', age: 18 };
const obj2 = obj1;
obj1.age = 20;
console.log(obj1); // { name: 'Tom', age: 20 }
console.log(obj2); // { name: 'Tom', age: 20 }
該方法可以將多個物件合併為一個物件,實現淺拷貝。
const obj1 = { name: 'Tom', age: 18 };
const obj2 = { gender: 'male' };
const obj3 = Object.assign({}, obj1, obj2);
console.log(obj3); // { name: 'Tom', age: 18, gender: 'male' }
使用深拷貝建立的物件,對其進行操作不會影響原有物件。實現物件的深拷貝需要使用一些特殊的方法。常見的深拷貝方法有 JSON.parse(JSON.stringify()) 和遞迴拷貝兩種方法。
JSON.parse(JSON.stringify()) 方法可以實現深拷貝,但是隻能處理物件中的原始型別,不能處理常式、正規表示式等型別。
const obj1 = { name: 'Tom', age: 18, hobbies: ['reading', 'music'] };
const obj2 = JSON.parse(JSON.stringify(obj1));
obj1.hobbies.push('travel');
console.log(obj1); // { name: 'Tom', age: 18, hobbies: [ 'reading', 'music', 'travel' ] }
console.log(obj2); // { name: 'Tom', age: 18, hobbies: [ 'reading', 'music' ] }
遞迴拷貝可以處理任何型別的資料,包括函數、正規表示式等。在拷貝物件時,需要遞迴遍歷物件的屬性,並將屬性值進行拷貝。
function deepClone(obj) {
// 判斷是否為物件或陣列
if (typeof obj !== 'object' || obj === null) {
return obj;
}
// 判斷是陣列還是物件
const newObj = Array.isArray(obj) ? [] : {};
// 遍歷物件或陣列
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
newObj[key] = deepCopy(obj[key]);
}
}
還可用第三方庫Lodash實現深淺拷貝。
在 JavaScript 中,物件是由鍵值對組成的集合,每個鍵值對就是物件的一個屬性,屬性名是鍵,屬性值可以是任何資料型別,包括基本型別、物件型別和函數型別等。物件可以通過字面量、建構函式以及 Object.create() 方法建立,也可以通過 Object.defineProperty() 方法定義屬性的 getter 和 setter。
JavaScript 的物件具有動態性,可以隨時新增或刪除屬性,也可以改變屬性的值。通過使用「點」或「中括號」語法可以存取和修改物件的屬性值。此外,可以使用 Object.keys()、Object.values()、Object.entries() 等方法來遍歷物件的屬性,也可以使用 for...in 和 for...of 迴圈遍歷物件屬性。