1.js基本类型的赋值关系
1 | var a = 5; |
2.数组赋值关系
1 | var a = [1,2,3]; |
在上面的例子中,b的值发生了改变影响到了a的值。这就构成了一种对象(函数)间的引用关系。1
2
3
4
5var a = [1,2,3];
var b = a;
b = [1,2,3,4];
alert(b); //[1,2,3,4]
alert(a); //[1,2,3]
在两个例子中,a和b都是引用关系,共用一块内存地址。第一个例子中,b的值发生了改变,a的值也跟着变化。
而第二个例子中,将一个新的数组分配给b则相当于给b开辟了新的内存空间,所以b的值不会改变a的值。
3.对象赋值与引用
下面再试一下对象的引用关系。1
2
3
4
5
6var obj = {
a:10
}
var obj2 = obj;
obj2.a = 20;
alert(obj.a);//20
如果对象直接用等于号赋值,改变obj2的值会使obj的值发生改变。1
2
3
4
5
6
7
8
9
10
11
12
13var obj = {
a:10
}
function copy(obj){
var newObj = {};
for(var attr in obj){
newObj[attr] = obj[attr];
}
return newObj;
}
var obj2 = copy(obj);
obj2.a = 20;
alert(obj.a);//10
在上面的例子中,我们需要赋值对象而不是引用对象的话,需要一个copy函数,将对象里面的值进行赋值操作。这种形式在JS中被称为浅拷贝。相对应的是深拷贝的模型。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var obj = {
a:{
b:10
}
}
function copy(obj){
var newObj = {};
for(var attr in obj){
newObj[attr] = obj[attr];
}
return newObj;
}
var obj2 = copy(obj);
obj2.a.b = 20;
alert(obj.a.b);//20
我们可以发现如果a里面的值是一个json的话,其实本质上还是一种引用关系。更改obj2,obj的值依然会受到影响。因为浅拷贝只是拷贝了一层,当我们用copy函数时还是把整体的对象赋值,所以还是对象的引用关系。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var obj = {
a:{
b:10
}
}
function deepCopy(obj){
if(typeof obj != 'object'){ //终止条件:obj不是对象作为递归的出口。
return obj;
}
var newObj = {};
for(var attr in obj){
newObj[attr] = deepCopy(obj[attr]);
}
return newObj;
}
var obj2 = deepCopy(obj);
obj2.a.b = 20;
alert(obj.a.b);//10
以上为深拷贝的例子。采用的是递归的方式,深拷贝可以复制多次直至结束。