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

微信公眾號:前端歷劫之路