了解之前,首先要知道什么是值类型和应用类型
- 常见的值类型有:数值、布尔值、null、undefined。
- 常见的引用类型有:对象、数组、函数。
用代码来详细理解
var arr1=[1,2,3,4];
var arr2=arr1;
arr1.push(5)
console.log(arr1);//1,2,3,4,5
console.log(arr2);//1,2,3,4,5
这里只改变了arr1,而arr2的值也改变了,这是因为定义arr1时,创建了一个空间,并且arr1指向它,再定义一个arr2,如果让arr2=arr1,就相当于把arr2也指向了arr1所指向的空间,所以改变arr1或arr2都可以改变这个空间里面的值,这就是引用类型。如果var arr2=[],让他等于一个新的数组,就会定义一个新的空间,而把arr2=arr1再次写进去时,相当于把arr1的指向有赋给了arr2,所以有变成上面的样子。仅个人理解。
有什么方法能让arr2==arr1&&arr2和arr1不会相互影响?
var arr1=[1,2,3,4,5];
var arr2=copy(arr1);
function copy(arr){
var arrs=[];
for(let i=0;i<arr.length;i++){
arrs.push(arr1[i])
}
return arrs
}
这样就可以实现想要的功能;
下面,如果是一个对象,对象里面有数组,实现上面相同的功能
var obj = { a:1, arr: [2,3] };
var shadowObj = shadowCopy(obj);
function shadowCopy(src) {
var dst = {};
for (var prop in src) {
console.log(src.hasOwnProperty(prop))//判断src里面有没有这个属性
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
改变obj,看shadowObj是否会发生变化
obj.name="小明"
console.log(obj);// { a:1, arr: [2,3],name:'小明' }
console.log( shadowObj );// { a:1, arr: [2,3] }
虽然看着的确是实现了功能,但是里面的数组还是有问题的;
obj.arr[0]=9;
console.log(obj.arr[0]);//9
console.log(shadowObj.arr[0]);//9
这是因为在遍历复制时,把数组对象直接的指向复制进去,所以这里的对象还是引用类型,如果需要的话,可以在上面代码的基础上面做判断
if(prop==arr){
for(){
把数组再遍历一遍
}
}