Vue淺拷貝和深拷貝實(shí)現(xiàn)方案
前言
在理解淺拷貝和深拷貝淺前,必須先理解基本數(shù)據(jù)類(lèi)型和引用數(shù)據(jù)類(lèi)型的區(qū)別。
一、數(shù)據(jù)類(lèi)型
1.1.基本數(shù)據(jù)類(lèi)型
字符串(Sring)、布爾值(Boolean)和數(shù)字(Number)
1.2.引用數(shù)據(jù)類(lèi)型
數(shù)組(Array)和對(duì)象(Object)
1.3.區(qū)別
基本數(shù)據(jù)類(lèi)型是存儲(chǔ)在棧內(nèi)存中。而引用類(lèi)型存放的值是指向數(shù)據(jù)的引用,而不是數(shù)據(jù)本身,真實(shí)數(shù)據(jù)是存放在堆內(nèi)存里,具體見(jiàn)如下:

二、淺拷貝
2.1.定義
淺拷貝是按位拷貝對(duì)象,它會(huì)創(chuàng)建一個(gè)新對(duì)象,這個(gè)對(duì)象有著原始對(duì)象屬性值的一份精確拷貝。如果屬性是基本類(lèi)型,拷貝的就是基本類(lèi)型的值;如果屬性是內(nèi)存地址(引用類(lèi)型),拷貝的就是內(nèi)存地址 ,因此如果其中一個(gè)對(duì)象改變了這個(gè)地址,就會(huì)影響到另一個(gè)對(duì)象。即默認(rèn)拷貝構(gòu)造函數(shù)只是對(duì)對(duì)象進(jìn)行淺拷貝復(fù)制(逐個(gè)成員依次拷貝),即只復(fù)制對(duì)象空間而不復(fù)制資源。
2.2.淺拷貝特點(diǎn)
對(duì)于基本數(shù)據(jù)類(lèi)型的成員對(duì)象,因?yàn)榛A(chǔ)數(shù)據(jù)類(lèi)型是值傳遞的,所以是直接將屬性值賦值給新的對(duì)象?;A(chǔ)類(lèi)型的拷貝,其中一個(gè)對(duì)象修改該值,不會(huì)影響另外一個(gè)。
var a = 10
var b = a
b = 20
console.log("a",a) //10
console.log("b",b) //20
對(duì)于引用類(lèi)型,比如數(shù)組或者類(lèi)對(duì)象,因?yàn)橐妙?lèi)型是引用傳遞,所以淺拷貝只是把內(nèi)存地址賦值給了成員變量,它們指向了同一內(nèi)存空間。改變其中一個(gè),會(huì)對(duì)另外一個(gè)也產(chǎn)生影響
var obj = {
a:"AAA"
}
var obj2 = obj
obj2.a = "BBB"
console.log("obj",obj) //{name: "BBB"}
console.log("obj2",obj2) //{name: "BBB"}
三、深拷貝
3.1.定義
深拷貝,在拷貝引用類(lèi)型成員變量時(shí),為引用類(lèi)型的數(shù)據(jù)成員另辟了一個(gè)獨(dú)立的內(nèi)存空間,實(shí)現(xiàn)真正內(nèi)容上的拷貝。
3.2.深拷貝特點(diǎn)
對(duì)于基本數(shù)據(jù)類(lèi)型的成員對(duì)象,因?yàn)榛A(chǔ)數(shù)據(jù)類(lèi)型是值傳遞的,所以是直接將屬性值賦值給新的對(duì)象?;A(chǔ)類(lèi)型的拷貝,其中一個(gè)對(duì)象修改該值,不會(huì)影響另外一個(gè)(和淺拷貝一樣)。
對(duì)于引用類(lèi)型,比如數(shù)組或者類(lèi)對(duì)象,深拷貝會(huì)新建一個(gè)對(duì)象空間,然后拷貝里面的內(nèi)容,所以它們指向了不同的內(nèi)存空間。改變其中一個(gè),不會(huì)對(duì)另外一個(gè)也產(chǎn)生影響。
var obj = {
a:"AAA"
}
var obj2 = {} // 創(chuàng)建新的對(duì)象
obj2 = obj
obj2.a = "BBB"
console.log("obj",obj) //{name: "AAA"}
console.log("obj2",obj2) //{name: "BBB"}
四、拷貝實(shí)現(xiàn)方案
4.1.Object.assign()
單級(jí)結(jié)構(gòu)時(shí)深拷貝,多級(jí)結(jié)構(gòu)淺拷貝,Object.assign()對(duì)象是用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象,將返回目標(biāo)對(duì)象。
a)單級(jí)結(jié)構(gòu)(一級(jí)拷貝是深拷貝):
var obj = {
a: 10,
}
var obj2 = Object.assign({}, obj);
obj2.a = 20
console.log("obj",obj); //{a: 10}
console.log("obj2",obj2) //{a: 20}b)多級(jí)結(jié)構(gòu)(一級(jí)拷貝是淺拷貝,修改二級(jí)對(duì)象還是會(huì)影響原對(duì)象):
var obj = {
a: 10,
b: {
c:"AAA",
d:666
}
}
var obj2 = Object.assign({}, obj);
obj2.b.c = "BBB"
console.log("obj",obj); //{a: 10,b: {c:"BBB",d:666}}
console.log("obj2",obj2); //{a: 10,b: {c:"BBB",d:666}}4.2.concat()
單級(jí)結(jié)構(gòu)時(shí)深拷貝,多級(jí)結(jié)構(gòu)淺拷貝
a)單級(jí)結(jié)構(gòu)(一級(jí)拷貝是深拷貝):
let arr = [1, 2];
let arr2 = arr.concat();
arr2[1] = 3;
console.log("arr",arr) //[1, 2]
console.log("arr2",arr2) //[1, 3]b)多級(jí)結(jié)構(gòu)(一級(jí)拷貝是淺拷貝):
let arr = [1, 2, {
a: 'AAA'
}];
let arr2 = arr.concat();
arr2[2].a = 'BBB';
console.log("arr",arr) //[1, 2, {a: 'BBB'}]
console.log("arr2",arr2) //[1, 2, {a: 'BBB'}]4.3.slice()
單級(jí)結(jié)構(gòu)時(shí)深拷貝,多級(jí)結(jié)構(gòu)淺拷貝
a)單級(jí)結(jié)構(gòu)(一級(jí)拷貝是深拷貝):
let arr = [1, 2, 3];
let arr2 = arr.slice();
arr2[1] = 4;
console.log("arr",arr) //[1, 2, 3]
console.log("arr2",arr2) //[1, 4, 3]b)多級(jí)結(jié)構(gòu)(一級(jí)拷貝是淺拷貝):
let arr = [1, 2, {a:'AAA'}];
let arr2 = arr.slice();
arr2[2].a = 'BBB';
console.log("arr",arr) //[1, 2, {a: 'BBB'}]
console.log("arr2",arr2) //[1, 2, {a: 'BBB'}]4.4.JSON.parse(JSON.stringify())
用JSON.stringify將對(duì)象轉(zhuǎn)成JSON字符串,再用JSON.parse()把字符串解析成對(duì)象,一去一來(lái),新的對(duì)象產(chǎn)生了,而且對(duì)象會(huì)開(kāi)辟新的棧,實(shí)現(xiàn)深拷貝。
單級(jí)多級(jí)均為深拷貝,但需要注意無(wú)法拷貝RegExp對(duì)象、function和symbol
let arr = [1, 2, {a:'AAA'}];
let arr2 = JSON.parse(JSON.stringify(arr))
arr2[2].a = 'BBB';
console.log("arr",arr) //[1, 2, {a: 'AAA'}]
console.log("arr2",arr2) //[1, 2, {a: 'BBB'}]4.5.cloneDeep()
單級(jí)多級(jí)均為深拷貝,使用lodash工具中cloneDeep方法實(shí)現(xiàn)深拷貝,需要通過(guò)npm引入lodash庫(kù)
npm i -save lodash //全局安裝
<script>
import _ from 'lodash';
export default {
name: 'Test',
mounted() {
const arr = [1, 2, { a: 'AAA' }];
const arr2 = _.cloneDeep(arr);
arr2[2].a = 'BBB';
console.log('arr', arr); // [1, 2, {a: 'AAA'}]
console.log('arr2', arr2); // [1, 2, {a: 'BBB'}]
},
};
</script>五、結(jié)論
| 類(lèi)型 | 第一級(jí)為基礎(chǔ)數(shù)據(jù)類(lèi)型 | 原數(shù)據(jù)中包含子對(duì)象 |
|---|---|---|
| 淺拷貝 | 改變不會(huì)使原始數(shù)據(jù)改變 | 改變會(huì)使原始數(shù)據(jù)改變 |
| 深拷貝 | 改變不會(huì)使原始數(shù)據(jù)改變 | 改變不會(huì)使原始數(shù)據(jù)改變 |
到此這篇關(guān)于Vue淺拷貝和深拷貝實(shí)現(xiàn)方案的文章就介紹到這了,更多相關(guān)vue淺拷貝和深拷貝區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue使用codemirror實(shí)現(xiàn)一個(gè)可插入自定義標(biāo)簽的textarea
這篇文章主要為大家詳細(xì)介紹了Vue如何使用codemirror實(shí)現(xiàn)一個(gè)可插入自定義標(biāo)簽的textarea,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02
VueX瀏覽器刷新如何實(shí)現(xiàn)保存數(shù)據(jù)
這篇文章主要介紹了VueX瀏覽器刷新如何實(shí)現(xiàn)保存數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
vue實(shí)現(xiàn)監(jiān)聽(tīng)localstorage值變化
這篇文章主要介紹了vue實(shí)現(xiàn)監(jiān)聽(tīng)localstorage值變化,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
Vue替代marquee標(biāo)簽超出寬度文字橫向滾動(dòng)效果
這篇文章主要介紹了Vue替代marquee標(biāo)簽超出寬度文字橫向滾動(dòng)效果,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Vue3利用vue-plugin-hiprint插件實(shí)現(xiàn)無(wú)預(yù)覽打印功能
在MES管理系統(tǒng)中需要實(shí)現(xiàn)條碼數(shù)據(jù)從接口返回后,直接調(diào)用打印機(jī)進(jìn)行打印,跳過(guò)瀏覽器的預(yù)覽確定那一步,在嘗試很多JS的方式和插件后,都無(wú)法實(shí)現(xiàn)該功能,所以本文介紹了Vue3如何利用vue-plugin-hiprint插件實(shí)現(xiàn)無(wú)預(yù)覽打印功能,需要的朋友可以參考下2025-04-04
Vue.js:使用Vue-Router 2實(shí)現(xiàn)路由功能介紹
本篇文章主要介紹了Vue.js:使用Vue-Router 2實(shí)現(xiàn)路由功能介紹,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02

