JS的深淺復(fù)制詳細(xì)
1、淺復(fù)制的意思
淺復(fù)制是僅僅對(duì)數(shù)據(jù)存放在棧內(nèi)的引用的復(fù)制,沒(méi)有復(fù)制引用指向堆內(nèi)的內(nèi)容。多個(gè)數(shù)據(jù)的淺復(fù)制,這復(fù)制多個(gè)引用,這多個(gè)引用共同指向堆內(nèi)的同一個(gè)內(nèi)容。當(dāng)一個(gè)淺復(fù)制數(shù)據(jù)做出修改,即堆內(nèi)的引用指向的內(nèi)容發(fā)生修改,這時(shí),其他通過(guò)引用指向這里的數(shù)據(jù)也會(huì)隨著改變。
let obj = {
a:1,
b:2,
c:{
c1:10,
c2:20
}
}
let objA = obj;
objA.a = 'a';
console.log(obj.a); // 'a'
console.log(objA.a); // 'a'
2、深復(fù)制的意思
深復(fù)制是指連同堆的內(nèi)容一塊復(fù)制,生成一個(gè)新的對(duì)象。多個(gè)深復(fù)制將是多個(gè)不同的對(duì)象,也就有不同的引用,也就指向不同的堆內(nèi)容。
3、使用深復(fù)制的原由
在平常開(kāi)發(fā)中,有時(shí)會(huì)有數(shù)據(jù)的傳遞與接收,當(dāng)拿到傳過(guò)來(lái)的數(shù)據(jù)后,難免需要對(duì)數(shù)據(jù)進(jìn)行加工和改造,為了不破壞原有數(shù)據(jù)結(jié)構(gòu),這時(shí)就可以使用深復(fù)制拷貝數(shù)據(jù),然后處理生成的新的數(shù)據(jù)。深復(fù)制也可以防止修改多個(gè)引用后引用混亂的問(wèn)題,減少BUG的產(chǎn)生機(jī)會(huì)。
4、可實(shí)現(xiàn)深復(fù)制的幾種方法
實(shí)現(xiàn)方式一:JSON的序列化與反序列化
let obj = {
a:1,
b:2,
c:{
c1:10,
c2:20
}
}
let objA = JSON.parse(JSON.stringify(obj));//JSON的序列化與反序列化
objA.a = 'a';
console.log(obj.a); // 1
console.log(objA.a); // 'a'
雖然JSON的序列化與反序列化可以實(shí)現(xiàn)深復(fù)制,但有幾個(gè)缺點(diǎn)需要注意:
date日期對(duì)象被轉(zhuǎn)成日期日期字符串- 沒(méi)法訪問(wèn)到原型
- 復(fù)制不了
undefined的屬性 NAN和無(wú)窮被轉(zhuǎn)為NULL
let d1 = new Date();
let obj = {
d1,
d2: undefined,
d3:NaN
}
let objD = JSON.parse(JSON.stringify(obj));
console.log(obj)
console.log(objD)
實(shí)現(xiàn)方式二:Object.assign()
let obj = {
a:1,
b:2,
c:{
c1:10,
c2:20
}
}
let objA = Object.assign(obj);
objA.a = 'a';
console.log(obj.a); // 1
console.log(objA.a); // 'a'
雖然Object.assign()可以實(shí)現(xiàn)深復(fù)制,但對(duì)于更深層次的對(duì)象引用也是僅僅淺復(fù)制。
let obj = {
a:1,
b:2,
c:{
c1:10,
c2:20
}
}
let objA = Object.assign(obj);
objA.c.c1 = 'c1'; //Object.assign()僅僅是一層深復(fù)制。
console.log(obj.c.c1); // 'c1'
console.log(objA.c.c1); // 'c1'
實(shí)現(xiàn)方式三:擴(kuò)展運(yùn)算符
let obj = {
a:1,
b:2,
c:{
c1:10,
c2:20
}
}
let objA = {...obj};;
objA.a = 'a';
console.log(obj.a); // 1
console.log(objA.a); // 'a'
雖然擴(kuò)展運(yùn)算符" … "可以實(shí)現(xiàn)深復(fù)制,但對(duì)于更深層次的對(duì)象引用也是僅僅淺復(fù)制。
let obj = {
a:1,
b:2,
c:{
c1:10,
c2:20
}
}
let objA = {...obj};
objA.c.c1 = 'c1'; //擴(kuò)展運(yùn)算符"..."同Object.assign()一樣,僅僅是一層深復(fù)制,不能多層深復(fù)制。
console.log(obj.c.c1); // 'c1'
console.log(objA.c.c1); // 'c1'
實(shí)現(xiàn)方式四:使用遞歸
想要實(shí)現(xiàn)深復(fù)制,且實(shí)現(xiàn)多層深復(fù)制則可以使用遞歸循環(huán)復(fù)制。
let obj = {
a:1,
b:2,
c:{
c1:10,
c2:20
}
}
const ReCopy = function (paramter) {
let target = null;
let isObject = paramter.constructor === Object;
let isArray = paramter.constructor === Array;
if (isObject || isArray) {
target = Array.isArray(paramter) ? [] : {};
for (let i in paramter) {
target[i] = ReCopy(paramter[i]);
}
} else {
target = paramter;
}
return target;
}
let objA = ReCopy(obj);
objA.c.c1 = 'c1';
console.log(obj.c.c1); // 10
console.log(objA.c.c1); // 'c1'
5、ladash深拷貝
lodash深復(fù)制是更專業(yè)的深復(fù)制方式。
安裝lodash
先初始化,生成package.json文件,然后使用一下命令安裝。
npm i -S lodash
引入lodash
var _ = require('lodash');
使用lodash
let obj = {
a:1,
b:2,
c:{
c1:10,
c2:20
}
}
let objA = _.cloneDeep(obj);
objA.c.c1 = 'c1';
console.log(obj.c.c1); // 10
console.log(objA.c.c1); // 'c1'
到此這篇關(guān)于JS的深淺復(fù)制詳細(xì)的文章就介紹到這了,更多相關(guān)JS的深淺復(fù)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js基礎(chǔ)語(yǔ)法與maven項(xiàng)目配置教程案例
本篇文章介紹了幾個(gè)javascript的基本語(yǔ)法和maven的配置教程。想學(xué)習(xí)javascript和maven的朋友們可以參考一下,希望能給你帶來(lái)幫助2021-07-07
JS封裝轉(zhuǎn)換前后端接口數(shù)據(jù)格式工具函數(shù)下劃線<=>大寫
這篇文章主要為大家介紹了JS優(yōu)雅封裝轉(zhuǎn)換前后端接口數(shù)據(jù)格式工具函數(shù)下劃線<=>大寫實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Qiankun Sentry 監(jiān)控異常上報(bào)無(wú)法自動(dòng)區(qū)分項(xiàng)目解決
這篇文章主要為大家介紹了Qiankun Sentry 監(jiān)控異常上報(bào)無(wú)法自動(dòng)區(qū)分項(xiàng)目解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
PHP:微信小程序 微信支付服務(wù)端集成實(shí)例詳解及源碼下載
這篇文章主要介紹了微信小程序 微信支付服務(wù)端集成實(shí)例詳解及源碼下載的相關(guān)資料,需要的朋友可以參考下2017-01-01
JS精髓原型鏈繼承及構(gòu)造函數(shù)繼承問(wèn)題糾正
這篇文章主要為大家介紹了JS精髓原型鏈繼承及構(gòu)造函數(shù)繼承問(wèn)題糾正,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
JS前端實(shí)現(xiàn)解除頁(yè)面禁止復(fù)制功能方法詳解
這篇文章主要為大家介紹了JS前端實(shí)現(xiàn)解除頁(yè)面禁止復(fù)制功能方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
JS中的every()對(duì)空數(shù)組總返回true原理分析
這篇文章主要為大家介紹了JS中的every()對(duì)空數(shù)組總返回true原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09

