在開發(fā)過程中,我碰到了一個問題,讓我找了好久問題在哪里,最后我發(fā)現(xiàn)是最開始賦值的時候沒有深拷貝值,導(dǎo)致了原本值被覆蓋污染,這里和大家分享下我的解決方法var i = 5; var j = i; j=1; console.log(i);//5 console.log(j);//1
我們正常賦值的邏輯是像上面一樣,復(fù)制一份下來,然后對復(fù)制的那一份進行操作,這樣的邏輯是對的,但是這樣的拷貝默認(rèn)是淺拷貝,當(dāng)出現(xiàn)以下情況時,這種寫法就會出問題 var i = {
value:5
};
var j = i;
j.value=1;
console.log(i.value);//1
console.log(j.value);//1
是不是覺得很奇怪,我在網(wǎng)上找了一下為什么,是有關(guān)淺拷貝和深拷貝的知識: (淺拷貝只是對指針的拷貝,拷貝后兩個指針指向同一個內(nèi)存空間,深拷貝不但對指針進行拷貝,而且對指針指向的內(nèi)容進行拷貝,經(jīng)深拷貝后的指針是指向兩個不同地址的指針,出現(xiàn)深淺拷貝的情況是當(dāng)對象為Object或Array時才會出現(xiàn)。)我分享下我的三種種解決方法:第一種,使用JSON.parse(JSON.stringify())let arr = [1, 3, {
username: ' kobe'
}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan';
console.log(arr, arr4)
原理: 用JSON.stringify將對象轉(zhuǎn)成JSON字符串,再用JSON.parse()把字符串解析成對象,一去一來,新的對象產(chǎn)生了,而且對象會開辟新的棧,實現(xiàn)深拷貝。第二種:Object.assign()var obj = { a: {a: "kobe", b: 39} };
var initalObj = Object.assign({}, obj);
initalObj.a.a = "wade";
console.log(obj.a.a); //wade
Object.assign() 方法可以把任意多個的源對象自身的可枚舉屬性拷貝給目標(biāo)對象,然后返回目標(biāo)對象。但是 Object.assign()進行的是淺拷貝,拷貝的是對象的屬性的引用,而不是對象本身。第三種:手寫遞歸方法遞歸方法實現(xiàn)深度克隆原理:遍歷對象、數(shù)組直到里邊都是基本數(shù)據(jù)類型,然后再去復(fù)制,就是深度拷貝
function getType(obj) {
//tostring會返回對應(yīng)不同的標(biāo)簽的構(gòu)造函數(shù)
var toString = Object.prototype.toString;
var map = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Object]': 'object'
};
if (obj instanceof Element) {
return 'element';
}
return map[toString.call(obj)];
}
//深拷貝
function deepClone(data) {
var type = getType(data);
var obj;
if (type === 'array') {
obj = [];
} else if (type === 'object') {
obj = {};
} else {
//不再具有下一層次
return data;
}
if (type === 'array') {
for (var i = 0, len = data.length; i < len; i++) {
obj.push(deepClone(data[i]));
}
} else if (type === 'object') {
for (var key in data) {
obj[key] = deepClone(data[key]);
}
}
return obj;
}
如果大家有其他方法,也歡迎在下面分享ヽ( ̄▽ ̄)?
|
|
|