關於Object
簡單記錄了關於js object的一些觀念和操作
JavaScript有八種資料型別,其中七種是原始型別(Primitive Type),另一種是物件型別(Object Type)。與只包含單一數值的原始型別相比,物件型別用來存儲相對複雜的實體。
關於Object操作
創建一個空物件的方法如下:
let foo = new Object(); // 使用construct
let foo = {}; // 使用literal
在創建對象的時候,能將屬性以key/value方式放入:
let foo = {
name: 'Alice',
age: 16,
};
並且在創建對象後可以任意添加、刪除和讀取
// 添加
foo.isMale = false;
// 刪除
delete foo.age;
// 讀取
console.log(foo.name); // Alice
console.log(foo);
// {
// "nname": "Alice",
// "isMale": false
// }
多詞屬性使用時要用方括號:
let test = {
'foo bar': false,
};
test['foo bar'] = true;
console.log(test['foo bar']);
delete test['foo bar'];
計算屬性
當創建一個對象,我們能在對object的literal中動態計算屬性名(Computed property names),如下:
const Number = 3;
const myObject = {
Num1: 5,
Num2: 10,
['Num' + Number]: 15,
};
console.log(myObject.Num3); // prints 15
測試存在屬性
// "key" in object
let user = { name: 'John', age: 18 };
console.log('age' in user); // true
為何不使用一般undefined判斷,因為有些情況下是要看是否有該屬性,而不是屬性值是undefined
let obj = {
test: undefined,
};
alert(obj.test === undefined); // true
alert('test' in obj); // true
alert(obj.test2 === undefined); // true
alert('test2' in obj); // false
遍歷object屬性值
使用"for...in"來遍歷一個object,如下:
for (key in object) {
}
// example
let user = {
name: 'John',
age: 18,
isMale: true,
};
for (let key in user) {
console.log(key); // name, age, isMale
console.log(user[key]); // John, 18, true
}
關於object的引用
object是"通過引用"來存儲和複製,原始類型是"做為一個整體"來複製。
原始類型如下:
let test = 'hello';
let test2 = test;
//產生兩個獨立的variable,並且每個variable存著字串
// ------- -------
// test | hello
// ------- -------
//
// ------- -------
// test2 | hello
// ------- -------
而object則是,賦予object的varaible存儲的不是object本身,而是該object在memory中的地址,也就是對該object的引用
let user = {
name: 'John',
};
let test = user; // 複製引用 (複製了該物件的地址)
該object被存儲在memory中的某個位置,並且變量user
保存的值,是對其的"引用",也就是該object的位址。並且"當一個object變量被複製,而該值是複製了該位址,而不是該object本身"。
let user = {
name: 'John',
};
let test = user;
// 修改test
test.name = 'Alice';
console.log(user.name); // Alice
我們來對比一下:
let a = {};
let b = a; // ref object
console.log(a == b); // true
consoel.log(a === b); // true
// create new object
let c = {};
console.log(a == c); // false
console.log(a === c); // false
我們能看到a和b引用同一個物件,所以他們相等。並且a和c是兩個獨立的物件,所以他們並不相等,即使都是空物件。
如何複製一個Object
一般情況下,複製一個object變量會創建一個對相同object的引用。所以該如何複製出一個獨立的object?
複製簡單object
1.創立一個新object,並對已有對象的屬性遍歷,並在原始類型值的層面去複製他們。
let user = {
name: 'John',
age: 18,
};
let obj = {};
for (let key in user) {
obj[key] = user[key];
}
2.也可以透過Object.assign
來達成(如果屬性名存在,會被覆蓋):
let user = {
name: 'John',
age: 18,
};
let height = {
height: 180,
};
let isMale = {
isMale: true,
};
Object.assign(user, height, isMale);
// user = { name: "John", age: 18, height: 180, isMale: true }
// Or
let obj2 = Object.assign({}, user);
3.或者是使用spread來進行clone:
let obj3 = { ...uer };
但上面的方法都是因為user的所有屬性都是原始屬性,但當屬性是其他對象的引用時就會有問題。
let user = {
name: 'John',
info: {
weight: 65,
height: 180,
},
};
如果使用先前的三個方法,會導致"新的object中的info",指向與"user中info"相同的引用。
那麼這時候我們就要使用到深拷貝(deep clone)。
複製複雜object
下面是幾種常用的方法:
- 使用
JSON.stringify(obj)
以及JSON.parse(JSONString)
- 使用lodash中的
_.cloneDeep(obj)
- 使用js原生api中的方法,
structuredClone(obj)
這裡記錄了關於object的一些簡易操作,之後會在新的文章添加一些新的紀錄。