1.对象和函数都是引用关系。
var a = 5; var b = a;//这个是一种赋值的关系,b改变不会影响到a。因为a,b都是变量
b += 3;
alert(b); //8
alert(a); //5
var a = [1,2,3];
var b = a;//a,b都是个对象。不是赋值的关系了,是一种引用,就是地址。不可能是复制了对象,对象再内存中太庞大了。
b.push(4);
alert(b); //1,2,3,4
alert(a); //1,2,3,4
此时a和b 共用一个地址,都是指向同一个数组的,b对象的元素发生改变,a也会改变。数组实际上一种引用。
举一个生活中的例子:一间房子有两把钥匙,这钥匙就是一种引用,当一个人用一把钥匙开门进去,把房间整理了一下,另一个人用另一把钥匙开门进去,还是那间房,那间房子就是被整理过的房子。
但是下面的例子,由于var b=[],这个操作,b又重新有了新的地址。
var a = [1,2,3];
var b = a;
b = [1,2,3,4];
alert(b); //1,2,3,4
alert(a); //1,2,3
2.复制的时候,不想改变原来的值
错误的例子:这个obj的a值发生了变化。
var obj = {
a : 10
};
var obj2 = obj;
obj2.a = 20;
alert(obj.a); //20
正确的方法:浅拷贝(只拷贝一层)
这样发现a的值没有再变化了。
var obj = {
a:10 //这是一种json的形式
};
function copy(obj){
var newObj={};
for(attr in obj){
newObj[attr]=obj[attr];
}
return newObj;
}
var obj2=copy(obj);
obj2.a=20;
console.info(obj.a);
console.info(obj2.a);
但是如果遇到深层的,如下面的:
var obj = {
a : { b : 10 }
};
function copy(obj){ //浅拷贝
var newObj = {};
for(var attr in obj){
newObj[attr] = obj[attr];
}
return newObj;
}
这时候,obj.a的值是20,而不是10
所以就涉及到了深拷贝,利用的是递归原理
首先看一下递归原理
//递归:递,是一层一层往下传。归是从最后一层往回走。
//1.函数调用函数自身,执行递的动作
//2.最后一次判断一个终止条件,可以执行归的动作
function test(n){
if(n==1){
console.trace();//追踪递归的过程
return 1;
}
return n*test(n-1);//每执行一次,不会return,直到符合了终止条件,再从后往前归
}
console.info(test(4));
可以看到效果:
深拷贝:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <script> var obj = { a : { b : 10 } }; function deepCopy(obj){ //深拷贝 if(typeof obj != 'object'){ console.trace(); return obj; } var newObj = {}; for(var attr in obj){ newObj[attr] = deepCopy(obj[attr]);//利用递归原理 } return newObj; } var obj2 = deepCopy(obj); obj2.a.b = 20; console.info(obj.a.b); //10 </script> </head> <body> </body> </html>