在開發程序中,我碰到了一個問題,讓我找了好久問題在哪里,最后我發現是最開始賦值的時候沒有深拷貝值,導致了原本值被覆寫污染,這里和大家分享下我的解決方法
var i = 5;
var j = i;
j=1;
console.log(i);//5
console.log(j);//1
我們正常賦值的邏輯是像上面一樣,復制一份下來,然后對復制的那一份進行操作,這樣的邏輯是對的,但是這樣的拷貝默認是淺拷貝,當出現以下情況時,這種寫法就會出問題
var i = {
value:5
};
var j = i;
j.value=https://www.cnblogs.com/smileZAZ/p/1;
console.log(i.value);//1
console.log(j.value);//1
是不是覺得很奇怪,我在網上找了一下為什么,是有關淺拷貝和深拷貝的知識:
(淺拷貝只是對指標的拷貝,拷貝后兩個指標指向同一個記憶體空間,深拷貝不但對指標進行拷貝,而且對指標指向的內容進行拷貝,經深拷貝后的指標是指向兩個不同地址的指標,出現深淺拷貝的情況是當物件為Object或Array時才會出現,)
我分享下我的三種種解決方法:
第一種,使用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將物件轉成JSON字串,再用JSON.parse()把字串決議成物件,一去一來,新的物件產生了,而且物件會開辟新的堆疊,實作深拷貝,
第二種: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() 方法可以把任意多個的源物件自身的可列舉屬性拷貝給目標物件,然后回傳目標物件,
但是 Object.assign()進行的是淺拷貝,拷貝的是物件的屬性的參考,而不是物件本身,
第三種:手寫遞回方法
遞回方法實作深度克隆原理:遍歷物件、陣列直到里邊都是基本資料型別,然后再去復制,就是深度拷貝
function getType(obj) {
//tostring會回傳對應不同的標簽的建構式
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;
}
如果大家有其他方法,也歡迎在下面分享ヽ( ̄▽ ̄)?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/16251.html
標籤:JavaScript
