ES6 中提供了一些對(duì)象的方法擴(kuò)展,其中的 Object.assgin() 讓我印象深刻,因?yàn)樗氖褂梅绞胶托Ч沉悖屛蚁肫鹆藬?shù)組的拼接方法:Array.prototype.concant()喷楣。他們有著一些相似的寫法和功能,當(dāng)然也有著一些區(qū)別恩伺,讓我們來(lái)一起探討吧赴背!
先來(lái)看看下面兩段代碼
let arr1 = ['a', 'b'];
let arr2 = ['a', 'c'];
let arr3 = arr1.concat(arr2);
// arr3: ['a', 'b', 'a', 'c']
let obj1 = {name: '張三', age: 22};
let obj2 = {name: '李四', sex: 'boy'};
let obj3 = Object.assgin(obj1, obj2);
// obj3: {name: '李四', age: 22, sex: 'boy'}
很顯然,他們都出色地完成了多個(gè)目標(biāo)的合并,但是仔細(xì)一看凰荚,還是有著一些不同之處:
concat() 方法與其說(shuō)是合并燃观,更像是拼接,把多個(gè)目標(biāo)按順序拼接到一起
Object.assgin() 方法則更傾向于合并便瑟,它同樣按照順序進(jìn)行合并缆毁,不同之處是重名的屬性,會(huì)保留最新的
這是他們最為初步的不同到涂,再把這幾個(gè)數(shù)組和對(duì)象進(jìn)行逐個(gè)打印觀察:
// 在 concat 合并之前脊框,我們給 arr2 本身,和它的原型對(duì)象践啄,分別加上不同的屬性
arr2.myLeng = function () {
console.log(this.length);
};
arr2.__proto__.proLeng = function () {
console.log(this.length);
};
// 使用 concat 進(jìn)行合并后浇雹,調(diào)用這兩個(gè)方法
arr3.myLeng(); // 報(bào)錯(cuò)
arr3.proLeng(); // 4
我們驚訝地發(fā)現(xiàn),原型對(duì)象上的方法 proLeng 也被復(fù)制過(guò)來(lái)了屿讽,但是數(shù)組本身上的方法 myLeng 并沒有成功被復(fù)制過(guò)來(lái)昭灵。
再看看 Object.assgin() 的表現(xiàn):
// 和上段代碼相似的插入位置
obj2.from = 'China';
obj2.__proto__.myAge = function () {
console.log(this.age);
};
console.log(obj3.from); // China
obj3.myAge(); // 22
顯然,復(fù)制過(guò)來(lái)的就是它本身的屬性伐谈,所以 from 存在沒有什么爭(zhēng)議虎锚,關(guān)鍵是 obj2 原型對(duì)象上的 myAge 方法同樣被繼承了
又可以總結(jié)一條:
concat() 方法創(chuàng)建出來(lái)的新數(shù)組,會(huì)繼承參與拼接數(shù)組原型對(duì)象上的屬性和方法衩婚,但是原數(shù)組本身的屬性和方法并不會(huì)被繼承窜护。
而 Object.assgin() 方法操作的源對(duì)象,會(huì)繼承參與合并對(duì)象“本身”和其“原型對(duì)象”上的屬性和方法
但是非春!熟悉原型鏈和原型對(duì)象的同學(xué)發(fā)現(xiàn)有點(diǎn)問題了柱徙!
注意:因?yàn)槭褂?proto 直接操作的是對(duì)應(yīng)構(gòu)造函數(shù)的原型對(duì)象,如數(shù)組的是 Array.prototype奇昙,對(duì)象的是 Object.prototype护侮,所以 concat 和 Object.assgin() 嚴(yán)格上來(lái)講并不是把這些原型對(duì)象上的方法給賦值繼承了過(guò)來(lái),而是操作 proto 的時(shí)候储耐,會(huì)影響全部由對(duì)應(yīng)構(gòu)造函數(shù)生成出來(lái)的對(duì)象或數(shù)組羊初。
那要怎么辦呢,很簡(jiǎn)單什湘,咱們自己自定義一個(gè)構(gòu)造函數(shù)长赞,給這個(gè)構(gòu)造函數(shù)的原型對(duì)象添加方法。然后用這個(gè)構(gòu)造函數(shù)進(jìn)行實(shí)例化闽撤,讓他參與 Object.assgin()得哆,看源對(duì)象是否會(huì)繼承:
let obj = {name: 'obj', type: 'a'};
// 自定義構(gòu)造函數(shù)
let Cobj = function (name) {
this.name = name;
};
// 給原型對(duì)象上添加方法
Cobj.prototype.getName = function () {
console.log(this.name);
};
let obj2 = new Cobj('obj2'); // 實(shí)例化
Object.assgin(obj, obj2);
console.log(obj); // {name: 'obj2', type: 'a'}
obj.getName(); // 報(bào)錯(cuò)
很遺憾,如果是自定義構(gòu)造函數(shù)實(shí)例出來(lái)的對(duì)象哟旗,則不會(huì)繼承他原型對(duì)象上的方法贩据。
結(jié)合上面的注意點(diǎn)栋操,我們可以很容易看出來(lái),其實(shí) Object.assgin() 并不會(huì)繼承參與合并對(duì)象的原型對(duì)象 prototype
最后把前面列舉的不同進(jìn)行一些匯總:
- 兩個(gè)方法都是按順序進(jìn)行和并饱亮,但是 Object.assgin 會(huì)把重復(fù)的屬性進(jìn)行保留最新值的操作矾芙,concat 不會(huì)
- concat 會(huì)創(chuàng)建一個(gè)新的數(shù)組,不會(huì)影響參與合并的原數(shù)組近上。而 Object.assgin 則是把第一個(gè)參數(shù)對(duì)象當(dāng)成操作對(duì)象蠕啄,把其他參數(shù)對(duì)象的屬性往它身上進(jìn)行合并,不會(huì)創(chuàng)建新對(duì)象戈锻,是對(duì)第一個(gè)參數(shù)對(duì)象的直接操作
- concat 創(chuàng)建出來(lái)的新數(shù)組歼跟,和Object.assgin 操作的對(duì)象,并不會(huì)繼承有參與合并對(duì)象“本身”及“原型對(duì)象”上的方法和屬性
以上就是一些小小的實(shí)驗(yàn)總結(jié)了格遭,為了詳細(xì)之余難免有些亢長(zhǎng)了哈街,可能有些觀點(diǎn)并不完全準(zhǔn)確,歡迎大家一起留言探討拒迅!
原文鏈接:https://blog.csdn.net/weixin_41399785/article/details/78926042