let arr1 = [1 , 2 , 3 , "hello" , "world"]; //原數組
拷貝數組:數組
let arr2 = arr1.slice(0); console.log(arr2); //打印新數組 [1 , 2 , 3 , "hello" , "world"]; //新數組
修改通過 slice() 拷貝過的新數組:code
arr2[3] = "Hello"; console.log(arr1); //打印舊數組 [1 , 2 , 3 , "hello" , "world"] console.log(arr2); //打印新數組 [1 , 2 , 3 , "Hello" , "world"]
<font color="red">結論:使用 slice() 方法拷貝數組,而後修改新數組,不會影響到舊數組的值。</font>對象
拷貝數組:遞歸
let arr3 = [].conat(arr1); console.log(arr3); //打印新數組 [1 , 2 , 3 , "hello" , "world"]; //新數組
修改通過 concat() 拷貝過的新數組內存
arr3[3] = "Hello"; console.log(arr1); //打印舊數組 [1 , 2 , 3 , "hello" , "world"] console.log(arr3); //打印新數組 [1 , 2 , 3 , "Hello" , "world"]
<font color="red">結論:使用 concat() 方法拷貝數組,而後修改新數組,不會影響到舊數組的值。</font>string
拷貝數組:io
let arr4 = arr1; console.log(arr4); //打印新數組 [1 , 2 , 3 , "hello" , "world"]; //新數組
修改通過簡單賦值過的新數組console
arr4[3] = "Hello"; console.log(arr1); //打印舊數組 [1 , 2 , 3 , "Hello" , "world"] console.log(arr4); //打印新數組 [1 , 2 , 3 , "Hello" , "world"]
<font color="red">結論:使用數組簡單賦值方法拷貝數組,而後修改新數組,會影響到舊數組的值。</font>function
<font color="red">緣由:這種簡單賦值的方法屬於數組的淺拷貝,數組arr1和數組arr4共用同一塊內存,其中一個數組改變,另外一個數組也會跟着改變。</font>object
let arr1 = [1 , 2 , 3 , {"name" : "張小二"} , {"sex" : "male"}]; //原數組
拷貝數組:
let arr2 = arr1.slice(0); console.log(arr2); //打印新數組 [1 , 2 , 3 , {"name" : "張小二"} , {"sex" : "male"}]; //新數組
修改通過 slice() 拷貝過的新數組:
arr2[3].name = "隔壁張小二"; console.log(arr1); //打印舊數組 [1 , 2 , 3 , {"name" : "隔壁張小二"} , {"sex" : "male"}] console.log(arr2); //打印新數組 [1 , 2 , 3 , {"name" : "隔壁張小二"} , {"sex" : "male"}]
<font color="red">
結論:使用 slice() 方法拷貝數組,而後修改新數組,會改變舊數組的值。
</font>
拷貝數組:
let arr3 = [].conat(arr1); console.log(arr3); //打印新數組 [1 , 2 , 3 , {"name" : "張小二"} , {"sex" : "male"}]; //新數組
修改通過 concat() 拷貝過的新數組
arr3[3].name = "隔壁張小二"; console.log(arr1); //打印舊數組 [1 , 2 , 3 , {"name" : "隔壁張小二"} , {"sex" : "male"}] console.log(arr3); //打印新數組 [1 , 2 , 3 , {"name" : "隔壁張小二"} , {"sex" : "male"}]
<font color="red">
結論:使用 concat() 方法拷貝數組,而後修改新數組,會改變舊數組的值。
</font>
一、數組的淺拷貝
(1)數組的直接賦值屬於數組的淺拷貝,JS存儲對象都是存內存地址的,因此淺拷貝會致使新數組和舊數組共用同一塊內存地址,其中一個數組變化,另外一個數組也會相應的變化。
(2)數組內部不含有引用類型,使用slice() 、concat() 和 assign() 方法都屬於數組的深拷貝,一個數組變化,另外一個數組不受影響。
(3)數組內部含有引用類型,使用slice() 、concat() 和 assign() 方法,非引用類型的值屬於深拷貝,引入類型的值屬於淺拷貝,一個數組變化,另外一個也會相應的變化。
方法一:遞歸
let cloneObj = function(obj){ let str, newobj = obj.constructor === Array ? [] : {}; if(typeof obj !== 'object'){ return; } else if(window.JSON){ str = JSON.stringify(obj), //系列化對象 newobj = JSON.parse(str); //還原 } else { for(var i in obj){ newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]; } } return newobj; }; let newArr = cloneObj(oldArr);
方法二:經過JSON解析解決
let newArr = JSON.parse(JSON.stringify(oldArr));