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