區(qū)別:
1梗掰、數(shù)據(jù)類型是基礎數(shù)據(jù)類型:名字和值都會儲存在棧內(nèi)存中,用淺拷貝不會存在什么問題
2蝠检、引用數(shù)據(jù)類型的數(shù)據(jù),名字存在棧內(nèi)存中挚瘟,值存在堆內(nèi)存中叹谁,但是棧內(nèi)存會提供一個引用的地址指向堆內(nèi)存中的值(對于淺拷貝,這樣是把飲用地址copy給對象存在隱患乘盖。無論是拷貝的對象內(nèi)的數(shù)據(jù)比變化焰檩,還是被拷貝的對象變化,都會引起對方的變化
image.png
image.png
實現(xiàn)淺拷貝的方法:
(1) for···in 循環(huán)遍歷拷貝第一層
function simpleCopy(obj) {
var objCopy = Array.isArray(obj) ? [] : {};
for (const key in obj) {
objCopy[key] = obj[key];
}
return objCopy;
}
(2) object.assign()
var obj = {
a: 1,
b: 2
}
var obj1 = Object.assign(obj);
obj1.a = 3;
console.log(obj.a) // 3
(3) 直接賦值
let a=[0,1,2,3,4],
b=a;
console.log(a===b);
a[0]=1;
console.log(a,b);
實現(xiàn)深拷貝的方法
(1)采用遞歸拷貝所有層級
function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : [];
if (obj && typeof obj === "object") {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
//判斷obj子元素是否為對象订框,如果是析苫,遞歸復制
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],[5,6]],
b=deepClone(a);
a[0]=2;
console.log(a,b);
(2) 通過JSON對象實現(xiàn)深拷貝
function deepClone(obj) {
var _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone;
}
缺點:無法對對象中的方法實行深拷貝,會顯示undefined
(3) 通過jQuery的extend進行深拷貝
$.extend( [deep ], target, object1 [, objectN ] )
(4) lodash 插件參拷貝
// 導入lodash
import _ from 'lodash'
// loodash.cloneDeep(obj)深拷貝
const form = _.cloneDeep(this.addForm)
form.goods_cat = form.goods_cat.join(',')
(5) 如果對象的value是基本數(shù)據(jù)類型 可以用Object.assign(),但是要把它賦值給一個空對象
var obj = {
a: 1,
b: 2
}
var obj1 = Object.assign({}, obj); // obj賦值給一個空{(diào)}
obj1.a = 3;
console.log(obj.a);// 1
(6)slice實現(xiàn)對數(shù)組的拷貝
// 當數(shù)組里面的值是基本數(shù)據(jù)類型衩侥,比如String浪腐,Number,Boolean時顿乒,屬于深拷貝
// 當數(shù)組里面的值是引用數(shù)據(jù)類型议街,比如Object,Array時璧榄,屬于淺拷貝
var arr1 = ["1","2","3"];
var arr2 = arr1.slice(0);
arr2[1] = "9";
console.log("數(shù)組的原始值:" + arr1 );
console.log("數(shù)組的新值:" + arr2 );
(7) concat 實現(xiàn)對數(shù)組的深拷貝
// 當數(shù)組里面的值是基本數(shù)據(jù)類型特漩,比如String,Number骨杂,Boolean時涂身,屬于深拷貝
var arr1 = ["1","2","3"];
var arr2 = arr1.concat();
arr2[1] = "9";
console.log("數(shù)組的原始值:" + arr1 );
console.log("數(shù)組的新值:" + arr2 );
// 當數(shù)組里面的值是引用數(shù)據(jù)類型,比如Object搓蚪,Array時蛤售,屬于淺拷貝
var arr1 = [{a:1},{b:2},{c:3}];
var arr2 = arr1.concat();
arr2[0].a = "9";
console.log("數(shù)組的原始值:" + arr1[0].a ); // 數(shù)組的原始值:9
console.log("數(shù)組的新值:" + arr2[0].a ); // 數(shù)組的新值:9
(8)直接使用var newObj = Object.create(oldObj),可以達到深拷貝的效果妒潭。
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用對象導致死循環(huán)悴能,如initalObj.a = initalObj的情況
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
} else {
obj[i] = prop;
}
}
return obj;
}
(9) 擴展符實現(xiàn)拷貝
// 當value是基本數(shù)據(jù)類型,比如String雳灾,Number漠酿,Boolean時,是可以使用拓展運算符進行深拷貝的
// 當value是引用類型的值谎亩,比如Object炒嘲,Array,引用類型進行深拷貝也只是拷貝了引用地址匈庭,所以屬于淺拷貝
var car = {brand: "BMW", price: "380000", length: "5米"}
var car1 = { ...car, price: "500000" }
console.log(car1); // { brand: "BMW", price: "500000", length: "5米" }
console.log(car); // { brand: "BMW", price: "380000", length: "5米" }
(10) 手動賦值實現(xiàn)深拷貝(實際開發(fā)過程中不常用)
let obj1 = {
a: 1,
b: 2
}
let obj2 = {
a: obj1.a,
b: obj1.b
}
obj2.a = 3;
alert(obj1.a); // 1
alert(obj2.a); // 3
---該文章內(nèi)容來自 http://www.reibang.com/p/1c142ec2ca45 主要用于方便個人查閱