举个例子体会一下
//第一个
var a =3;
var b=a;
a=4;
console.log(b);//输出3
//第二个
var initFriut =[];
var haveFriut =[{'type':'苹果',num:1},
{'type':'梨子',num:2},
{'type':'香蕉',num:3}];
//赋值数组对象值给initPax
initFriut = haveFriut;
//输出的结果一致
console.log(initFriut);
console.log(haveFriut);
haveFriut[0].num = 4;
console.log(initFriut[0].num);//输出结果为4
//若想拷贝带有对象的数组,且不影响原有数据;那么只能采用深拷贝的方式;
initFriut = [].concat(JSON.parse(JSON.stringify(haveFriut)));
haveFriut[0].num = 5;//此时更改不影响initFriut
console.log(initFriut[0].num);//输出的结果为4
这里引入基本数据类型与引用数据类型的概念了。
js基本数据类型:
number,string,boolean,null,undefined五类。
基本类型–名值存储在栈内存中,
当你b=a复制时,栈内存会为b新开辟一个内存,
引用数据类型(Object类)有:
常规名值对的无序对象{a:1},数组[1,2,3],以及函数等。
引用数据类型–名存在栈内存中
值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值
当b=a进行拷贝时,其实复制的是a的引用地址,而并非堆里面的值。
这下明白例子中失败引用的问题了吗?
那什么是深拷贝呢?
深拷贝:是拷贝对象各个层级的属性;而非只拷贝一块儿引用的地址;
实现深拷贝这里就需要用到JSON.stringify 与 JSON.parse
除此之外它们还能结合localStorage实现对象数组存储。
除了这种方式还可以使用:
//1.可以借用JQ的extend方法。
//效果与上面方法一样,只是需要依赖JQ库。
$.extend( [deep ], target, object1 [, objectN ] )
//deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
//target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
//object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。
//------------------------------------------------------------
//直接使用var newObj = Object.create(oldObj)可以达到深拷贝的效果。
//利用循环挨个拷贝数组里面的对象,从而达到想要的效果
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i];
// 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? prop : Object.create(prop);
} else {
obj[i] = prop;
}
}
return obj;
}