首頁  >  問答  >  主體

複製數組的值

<p>當在JavaScript中將一個陣列複製到另一個陣列時:</p> <pre class="brush:php;toolbar:false;">var arr1 = ['a','b','c']; var arr2 = arr1; arr2.push('d'); // 現在,arr1 = ['a','b','c','d']</pre> <p>我意識到<code>arr2</code>引用的是與<code>arr1</code>相同的數組,而不是一個新的、獨立的陣列。我該如何複製數組以獲得兩個獨立的數組? </p>
P粉002546490P粉002546490426 天前486

全部回覆(2)我來回復

  • P粉795311321

    P粉7953113212023-08-21 11:38:17

    在Javascript中,深拷貝技術取決於陣列中的元素。讓我們從這裡開始。

    三種類型的元素

    元素可以是:字面值、字面結構或原型。

    // 字面值(类型1)
    const booleanLiteral = true;
    const numberLiteral = 1;
    const stringLiteral = 'true';
    
    // 字面结构(类型2)
    const arrayLiteral = [];
    const objectLiteral = {};
    
    // 原型(类型3)
    const booleanPrototype = new Bool(true);
    const numberPrototype = new Number(1);
    const stringPrototype = new String('true');
    const arrayPrototype = new Array();
    const objectPrototype = new Object(); // 或者 `new function () {}
    

    從這些元素中,我們可以建立三種類型的陣列。

    // 1) 字面值数组(布尔值、数字、字符串) 
    const type1 = [ true, 1, "true" ];
    
    // 2) 字面结构数组(数组、对象)
    const type2 = [ [], {} ];
    
    // 3) 原型对象数组(函数)
    const type3 = [ function () {}, function () {} ];
    

    深拷貝技術取決於這三種陣列類型

    根據數組中元素的類型,我們可以使用各種技術進行深拷貝。

    深拷貝技術

    基準測試

    https://www.measurethat.net/Benchmarks/Show/17502/0/deep-copy-comparison

    • 字面值數組(類型1)
      # 可以使用[ ...myArray ]myArray.splice(0)myArray.slice()myArray.concat() 技術來深拷貝只包含字面值(布林值、數字和字串)的陣列;其中在Chrome中,slice() 的效能最高,在Firefox中,擴充運算子. .. 的性能最高。

    • 字面值數組(類型1)和字面結構數組(類型2)
      # 可以使用 JSON.parse(JSON.stringify(myArray)) 技術來深拷貝字面值(布林值、數字、字串)和字面結構(陣列、物件),但不能拷貝原型物件。

    • 所有陣列(型別1、型別2、型別3)

      • 可以使用Lo-dashcloneDeep(myArray)jQueryextend(true, [], myArray) 技術來深拷貝所有類型的數組。其中Lodash的 cloneDeep() 技術性能最高。
      • 對於那些避免使用第三方函式庫的人來說,下面的自訂函數可以深拷貝所有類型的數組,效能低於cloneDeep(),但高於extend(true )
    function copy(aObject) {
      // 防止未定义的对象
      // if (!aObject) return aObject;
    
      let bObject = Array.isArray(aObject) ? [] : {};
    
      let value;
      for (const key in aObject) {
    
        // 防止自引用到父对象
        // if (Object.is(aObject[key], aObject)) continue;
        
        value = aObject[key];
    
        bObject[key] = (typeof value === "object") ? copy(value) : value;
      }
    
      return bObject;
    }
    

    所以回答這個問題...

    問題

    var arr1 = ['a','b','c'];
    var arr2 = arr1;
    

    答案

    因為arr1 是一個包含字面值(布林值、數字或字串)的數組,你可以使用上面討論的任何深拷貝技術,其中slice() 和擴充運算子... 的效能最高。

    arr2 = arr1.slice();
    arr2 = [...arr1];
    arr2 = arr1.splice(0);
    arr2 = arr1.concat();
    arr2 = JSON.parse(JSON.stringify(arr1));
    arr2 = copy(arr1); // 需要自定义函数,上面已提供
    arr2 = _.cloneDeep(arr1); // 需要Lo-dash.js
    arr2 = jQuery.extend(true, [], arr1); // 需要jQuery.js
    

    回覆
    0
  • P粉217784586

    P粉2177845862023-08-21 09:59:42

    使用這個:

    let oldArray = [1, 2, 3, 4, 5];
    
    let newArray = oldArray.slice();
    
    console.log({newArray});

    回覆
    0
  • 取消回覆