js深拷貝淺拷貝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
// 在JS中,數(shù)據(jù)類型分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型兩種,對(duì)于基本數(shù)據(jù)類型來(lái)說(shuō),它的值直接存儲(chǔ)在棧內(nèi)存中,
// 而對(duì)于引用類型來(lái)說(shuō),它在棧內(nèi)存中僅僅存儲(chǔ)了一個(gè)引用,而真正的數(shù)據(jù)存儲(chǔ)在堆內(nèi)存中
// 當(dāng)基本類型實(shí)現(xiàn)淺拷貝,存在棧內(nèi)存中,那么相互獨(dú)立,互不影響。
// 當(dāng)復(fù)雜類型實(shí)現(xiàn)淺拷貝,新對(duì)象與舊對(duì)象仍然同時(shí)指向堆內(nèi)存的同一屬性,互不獨(dú)立,相互影響。
// 基本數(shù)據(jù)類型
var a = "1";
var b = a;
a = 2;
console.log(b);
// 引用數(shù)據(jù)類型
var arr = [1,2,3];
var newArr = copy(arr); //[1,2,3]
newArr.push(4); //[1,2,3,4]
console.log(arr); //[1,2,3,4]
// 當(dāng)我們創(chuàng)建arr數(shù)組時(shí),arr被分配到了堆內(nèi)存中,在棧內(nèi)存留下可以尋找到的指針,
// 也就是說(shuō)當(dāng)我們創(chuàng)建新數(shù)組newArr時(shí),賦予newArr的是arr在棧中的地址(指針),
// 其實(shí)仍與舊數(shù)組arr共享同一個(gè)內(nèi)存,所以修改新數(shù)組newArr后,舊數(shù)組arr也會(huì)被修改
// 深拷貝
// 它可以將復(fù)雜類型的數(shù)據(jù)相互獨(dú)立出來(lái),互不影響
// 深拷貝不會(huì)拷貝引用類型的引用,而是將引用類型的值全部拷貝一份,形成一個(gè)新的引用類型,
// 這樣就不會(huì)發(fā)生引用錯(cuò)亂的問(wèn)題,使得我們可以多次使用同樣的數(shù)據(jù),而不用擔(dān)心數(shù)據(jù)之間會(huì)起沖突
// 1、
function copy(obj) {
if(typeof obj == "object") { //判斷是否復(fù)雜類型
var result = obj.constructor == Array ? [] : {};//判斷數(shù)組類型或是object,數(shù)組即result=[],object即result={}
for(let i in obj) {
result[i] = typeof obj[i] == "object" ? copy(obj[i]) : obj[i]//判斷數(shù)據(jù)每一項(xiàng)是否是object
}
} else {
var result = obj //基本類型直接拷貝
}
return result;
}
// 2、
function deepClone(target) {
// 定義一個(gè)變量
let result;
// 如果當(dāng)前需要深拷貝的是一個(gè)對(duì)象的話
if (typeof target === 'object') {
// 如果是一個(gè)數(shù)組的話
if (Array.isArray(target)) {
result = []; // 將result賦值為一個(gè)數(shù)組,并且執(zhí)行遍歷
for (let i in target) {
// 遞歸克隆數(shù)組中的每一項(xiàng)
result.push(deepClone(target[i]))
}
// 判斷如果當(dāng)前的值是null的話;直接賦值為null
} else if(target===null) {
result = null;
// 判斷如果當(dāng)前的值是一個(gè)RegExp對(duì)象的話,直接賦值
} else if(target.constructor===RegExp){
result = target;
}else {
// 否則是普通對(duì)象,直接for in循環(huán),遞歸賦值對(duì)象的所有值
result = {};
for (let i in target) {
result[i] = deepClone(target[i]);
}
}
// 如果不是對(duì)象的話,就是基本數(shù)據(jù)類型,那么直接賦值
} else {
result = target;
}
// 返回最終結(jié)果
return result;
}
</script>
</html>
作者:Vam的金豆之路
主要領(lǐng)域:前端開(kāi)發(fā)
我的微信:maomin9761
微信公眾號(hào):前端歷劫之路