作者:浪里行舟
連接:https://juejin.im/post/6844904197595332622
來源:掘金
淺拷貝:
創建一個新的對象並賦予該對象另一個對象的所有第一層屬性,如果屬性是普通類型則複製新的對象,如果屬性是引用類型則複製內存地址給他。
深拷貝:
和拷貝的對象一模一樣,而且內存地址完全不同(一個對象改變不同不會影響另一個對象)
聽起來文謅謅的我們直接來看示意圖
假設今天拷貝公司一有一個員工,他叫做淺拷貝,今天他的工作內容很特別,剛好跟他的名子一樣,就是淺拷貝一個對象。這一天他一如既往地在拷貝一個對象foo。
先來看看foo的長相
let foo = {
bar: 5,
baz: {
name: 'Mike',
age: 15
}
}
淺拷貝本身是一個很怕麻煩的人,對他來說拷貝任務只需要看起來完成就好,其他沒差啦~~
所以對淺拷貝來說其實 foo 是長這樣
可以看到,非常的隨便,因此他就開始了他的拷貝任務
可以看到其實就是複製第一層地址給他們,相信聰明的各位會發現,如果今天我
更改新foo.baz對象的值(比方說 新foo.baz.age = 20) 會影響到foo.baz
很合理啊!因為內存地址都相同啊
繼續淺拷貝的例子,只是今天換成拷貝公司的深拷貝先生來拷貝foo!
深拷貝是一個超級嚴謹的員工,所以他一定要把所有的東西都創新一遍,所以對深拷貝員工來說,他要的foo長這樣
哇看起來是真的累人,開始他的工作吧
哇簡直可怕的認真,他居然為了對象裡的對象(foo.baz) 開創了新的地址並複製。
可能你會覺得還好,沒有很累人啊。但是他會其實不只第二層,他會把所有的東西都這樣跑一遍意思就是假設
今天 foo.baz.name 不是一個一般類型的話就要繼續重複剛剛的流程下去
如果已經懂得人可以跳到下一個part
比方說今天的 foo.baz.name 長這樣
foo.baz.name = {
id: 01,
name: 'Mike'
}
那代表我們還得繼續往下複製下去
可見深拷貝是一個多麼認真的魔人
Object.assign(target, ...sources)
把多個原對象的可枚舉屬性拷貝給目標對象
例子:
let foo = {
bar: 5,
baz: {
name: 'Mike',
age: 15
}
}
let copyFoo = Object.assign({}, foo)
let foo = {
bar: 5,
baz: {
name: 'Mike',
age: 15
}
}
const _ = require('loadash');
var copyFoo = _.clone(foo);
ES6新增的,可以實現跟Object.assign一樣效果
let foo = {
bar: 5,
baz: {
name: 'Mike',
age: 15
}
}
let copyFoo = {...foo}
// 證明他也是淺拷貝
foo.baz.name = '被改了!'
console.log(copyFoo);
主要用於數組
let foo = [1, 5, {name: 'Mike'}]
let copyFoo = foo.concat()
foo[2].name = '被改了!'
console.log(copyFoo);
主要用於數組
let foo = [1, 5, {name: 'Mike'}]
let copyFoo = foo.slice()
foo[2].name = '被改了!'
console.log(copyFoo);
明天會開一篇來討論~~