1.屬性的簡潔表示法
1.1 ES6允許在對象之中,直接寫變量。這時雹有,屬性名為變量名, 屬性值為變量的值稽煤。例如:
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}
//等同于
const baz = {foo: foo};
1.2 除了屬性簡寫,方法也可以簡寫疼进。例如:
const o = {? //react native采用的就是這種寫法
? method() {
? ? return "Hello!";
? }
};
// 等同于
const o = {
? method: function() {
? ? return "Hello!";
? }
};
1.3 如果某個方法的值是一個Generator函數(shù),前面需要加上星號。
const obj = {
? * m() {
? ? yield 'hello world';
? }
};
2.屬性名表達式
2.1 定義對象的屬性聚请,有兩種方法
1)直接用標(biāo)識符作為屬性名,例如:
obj.foo = true;
2)用表達式作為屬性名稳其,這時要將表達式放在方括號之內(nèi)驶赏。例如:
obj['a' + 'bc'] = 123;
2.2 使用字面量方式定義對象炸卑,即使用大括號,ES5與ES6存在不同之處:
1)ES5中只能使用方法一(標(biāo)識符)定義屬性煤傍。
2)ES6允許把表達式放在方括號內(nèi)矾兜。例如:
let obj = {
? [propKey]: true,
? ['a' + 'bc']: 123
};
2.3 表達式還可以用于定義方法名。例如:
let obj = {
? ['h' + 'ello']() {
? ? return 'hi';
? }
};
obj.hello() // hi
2.4 注意:
1)屬性名表達式與簡潔表示法患久,不能同時使用椅寺,會報錯。例如:
// 報錯
const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };
2)屬性名表達式如果是一個對象蒋失,默認情況下會自動將對象轉(zhuǎn)為字符串[object Object]返帕,這一點要特別小心。例如:
const keyA = {a: 1};
const keyB = {b: 2};
const myObject = {
? [keyA]: 'valueA',
? [keyB]: 'valueB'
};
myObject // Object {[object Object]: "valueB"}
上面代碼中篙挽,[keyA]和[keyB]得到的都是[object Object]荆萤,所以[keyB]會把[keyA]覆蓋掉,而myObject最后只有一個[object Object]屬性铣卡。
3.方法的name屬性
3.1 功能:方法的name屬性返回函數(shù)名(即方法名)链韭。
3.2 注意:如果對象的方法使用了取值函數(shù)(getter)和存值函數(shù)(setter),則name屬性不是在該方法上面煮落,而是該方法的屬性的描述對象的get和set屬性上面敞峭,返回值是方法名前加上get和set。
3.2 有兩種特殊情況:bind方法創(chuàng)造的函數(shù)蝉仇,name屬性返回bound加上原函數(shù)的名字旋讹;Function構(gòu)造函數(shù)創(chuàng)造的函數(shù),name屬性返回anonymous轿衔。
3.3 如果對象的方法是一個Symbol值沉迹,那么name屬性返回的是這個Symbol值的描述。
4.Object.is()
4.1 功能:用來比較兩個值是否嚴(yán)格相等害驹,與嚴(yán)格比較運算符(===)的行為基本一致鞭呕。
4.2 Object.is()與“===”的不同之處,有兩個:一是+0不等于-0宛官,二是NaN等于自身葫松。例如:
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
5.Object.assign()
5.1 功能:Object.assign方法用于對象的合并,將源對象(source)的所有可枚舉屬性摘刑,復(fù)制到目標(biāo)對象(target)进宝。Object.assign方法的第一個參數(shù)是目標(biāo)對象,后面的參數(shù)都是源對象枷恕。
5.2 注意點:
1)淺拷貝:Object.assign方法實行的是淺拷貝党晋,而不是深拷貝。也就是說,如果源對象某個屬性的值是對象未玻,那么目標(biāo)對象拷貝得到的是這個對象的引用灾而。
上面代碼中,源對象obj1的a屬性的值是一個對象扳剿,Object.assign拷貝得到的是這個對象的引用旁趟。這個對象的任何變化,都會反映到目標(biāo)對象上面庇绽。例如:
const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
2)同名屬性的替換:對于這種嵌套的對象锡搜,一旦遇到同名屬性,Object.assign的處理方法是替換瞧掺,而不是添加耕餐。例如:
const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }
3)數(shù)組的處理:Object.assign可以用來處理數(shù)組,但是會把數(shù)組視為對象辟狈。例如:
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]
上面代碼中肠缔,Object.assign把數(shù)組視為屬性名為0、1哼转、2的對象明未,因此源數(shù)組的0號屬性4覆蓋了目標(biāo)數(shù)組的0號屬性1。
4)取值函數(shù)的處理:Object.assign只能進行值的復(fù)制壹蔓,如果要復(fù)制的值是一個取值函數(shù)趟妥,那么將求值后再復(fù)制。
const source = {? get foo() { return 1 }
};
const target = {};
Object.assign(target, source)
// { foo: 1 }
上面代碼中庶溶,source對象的foo屬性是一個取值函數(shù)煮纵,Object.assign不會復(fù)制這個取值函數(shù),只會拿到值以后偏螺,將這個值復(fù)制過去。
5.3 常見用途:
1)為對象添加屬性
2)為對象添加方法
3)克隆對象
4)合并多個對象
5)為屬性指定默認值
1.什么是淺拷貝匆光?
淺復(fù)制是對對象地址的復(fù)制套像,并沒有開辟新的棧,也就是復(fù)制的結(jié)果是兩個對象指向同一個地址终息,修改其中一個對象的屬性夺巩,則另一個對象的屬性也會改變,而深復(fù)制則是開辟新的棧周崭,兩個對象對應(yīng)兩個不同的地址柳譬,修改一個對象的屬性,不會改變另一個對象的屬性续镇。
2.let c = {'a':1, 'b':2};let b = c;這是不是淺拷貝美澳?
let b = c;
b.a = 3;
console.log('===c==='+JSON.stringify(c));//===c==={"a":3,"b":2}? 改變b,c也隨之改變,淺拷貝
3.怎么進行深拷貝?
使用JSON解析解決:
let c = {a:1,b:2};
? ? let d = JSON.parse(JSON.stringify(c));
? ? d.a = 3
? ? console.log('===c==='+JSON.stringify(c));//===c==={"a":1,"b":2}
? ? console.log('===d==='+JSON.stringify(d));//===d==={"a":3,"b":2}
4.只有這一種解決方案?這種解決方案的優(yōu)缺點是什么制跟?
不止這種方法舅桩,這種方法的優(yōu)點是簡單,缺點是無法復(fù)制方法雨膨。
let c = {a:1,b:2,func:function(){return 'function'}};
let d = JSON.parse(JSON.stringify(c));
d.a = 3
console.log('===c==='+JSON.stringify(c)+',===c.c==='+c.func);
//===c==={"a":1,"b":2},===c.c===function func() {return 'function';}
console.log('===d==='+JSON.stringify(d)+',===d.c==='+d.func);
//===d==={"a":3,"b":2},===d.c===undefined
https://stackoverflow.com/questions/38416020/deep-copy-in-es6-using-the-spread-sign