1. 概念
在JavaScript中,拷貝一般是指變數的復制程序,
對于簡單型別,拷貝就是直接賦值的程序;
對于復雜型別,淺拷貝是指復制物件的參考地址的程序,如果修改了源物件的某個屬性,由于參考相同,所以目標物件的屬性也會被改變,
2. 測驗
// 測驗1
function test() {
var obj = {
id: 1,
name: 'Tom',
props: {
age: 18,
},
color: ['red', 'green'],
};
const res = copy(obj);
obj.props.age = 20; // 修改原物件的屬性值,觀察目標物件是否受影響
console.log(res.props.age === 20); // true // 表示目標物件受到影響
}
復制代碼
3. 實作
function copy(source) {
let res = {};
for (const key in source) {
res[key] = source[key];
}
return res;
}
復制代碼
二、深拷貝
1. 概念
對于復雜型別,淺拷貝是指完全復制一個全新的物件,修改原物件的屬性,不會影響目標物件,因為復制出來的2個物件參考不同,也就是指向記憶體的地址不同,
2. 測驗
function test() {
var obj = {
id: 1,
name: 'Tom',
props: {
age: 18,
},
color: ['red', 'green'],
};
let res = deepCopy(obj);
obj.props.age = 20; // 修改原物件的屬性值,觀察目標物件是否受影響
console.log(res.props.age === 18); // true // 表示不受影響
}
復制代碼
3. 實作
// 第一版
function deepCopy(target, source) {
for (const key in source) {
const item = source[key];
if (Array.isArray(item)) {
target[key] = [];
deepCopy(target[key], item);
} else if (typeof element === 'object') {
target[key] = {};
deepCopy(target[key], item);
} else {
target[key] = item;
}
}
}
復制代碼
仔細觀察發現第一個版本有很多冗余的代碼,改造一下:
// 第二版
function deepCopy(target, source) {
for (const key in source) {
const item = source[key];
if (typeof item === 'object') {
deepCopy(Array.isArray(target[key]) ? [] : {}, item);
} else {
target[key] = item;
}
}
}
復制代碼
三、總結
-
如果一個已知物件,屬性都是簡單型別,可以通過
JSON.parse(JSON.stringify(source))來實作深拷貝 -
但是如果原物件中有函式、日期、正則等復雜型別的屬性,轉換后會出現屬性丟失問題
-
產生這種問題的根本原因是
JSON不支持這些上述復雜型別,具體解釋可以看這里,
// 測驗 JSON方式的深拷貝
function test() {
var obj = {
name: 'bird',
speak: function() {
console.log('ji ji ji')
}
}
let res = deepClone(obj);
console.log(res.speak); // undefined // 表示方法屬性丟失了
}
function deepClone(source) {
return JSON.parse(JSON.stringify(source));
}
本文首發于前端黑洞網,博客園同步跟新
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/270855.html
標籤:jQuery
下一篇:了解jQuery
