在項目中遇到了一個問題,js 中,爲了保存個對象數組不被改變,javascript
page.uploadMember = res.result.list; page.nameArr = res.result.list; //保存的page.uploadMember是爲了備份不被改動, //代碼中有對page.nameArr進行操做
最後在取page.uploadMember的時候發現它也跟着改變了,做爲一個長期寫PHP,javascript研究不深刻的人百思不得其解,研究了很久都沒發現問題,最後請教了一下前端開發,發現JavaScript有深拷貝和淺拷貝的概念;前端
淺拷貝:假設B複製了A,當修改A時,看B是否會發生變化,若是B也跟着變了,說明這是淺拷貝,A、B是指向一個地址的;java
深拷貝:建立一個新的和原始字段的內容相同的字段,是兩個同樣大的數據段;兩個的地址是吧不同的;數組
這裏提到一點:函數
var a = []; var b = []; console.log(a == b); //false a和b地址不同,只是值敲剛好相等; var c = a; console.log(a == c); //true a和c地址同樣 c[0] = 1; console.log(a); //[1] a隨着c改變而改變,這就是淺拷貝
JavaScript的基本數據類型:number,string,boolean,null,undefined五類。spa
引用數據類型 (Object類) 有常規名值對的無序對象{a:1},數組[1,2,3],以及函數等。code
基本類型--名值存儲在棧內存中對象
引用數據類型--名存在棧內存中,值存在於堆內存中,可是棧內存會提供一個引用的地址指向堆內存中的值blog
因此淺拷貝值存在於引用數據類型,c=a進行拷貝時,其實複製的是a的引用地址,而並不是堆裏面的值。遞歸
實現深拷貝的方法:
1封裝一個方法,遞歸拷貝對象各個層級的屬性:
複製代碼 function deepClone(obj){ let objClone = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ for(key in obj){ if(obj.hasOwnProperty(key)){ //判斷ojb子元素是否爲對象,若是是,遞歸複製 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //若是不是,簡單複製 objClone[key] = obj[key]; } } } } return objClone; } let a=[1,2,3,4], b=deepClone(a); a[0]=2; console.log(a,b);
2.除了遞歸,咱們還能夠借用JSON對象的parse和stringify
function deepClone(obj){ let _obj = JSON.stringify(obj), objClone = JSON.parse(_obj); return objClone } let a=[0,1,[2,3],4], b=deepClone(a); a[0]=1; a[2][0]=1; console.log(a,b);
3.除了上面兩種方法以外,咱們還能夠借用JQ的extend方法。
$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷貝,爲true爲深拷貝,爲false,則爲淺拷貝
target Object類型 目標對象,其餘對象的成員屬性將被附加到該對象上。
object1 objectN可選。 Object類型 第一個以及第N個被合併的對象。
let a=[0,1,[2,3],4], b=$.extend(true,[],a); a[0]=1; a[2][0]=1; console.log(a,b);