传值和传址
传值:简单数据类型就是 传值 和 传址;复杂数据类型 赋值 就是 传址
js :简单数据类型是传值;复杂数据类型是传址(array,object,function...);
简单数据类型存在内存的栈zhan里(有序的);
复杂数据类型存在内存的堆里(无序的)。注意:复杂数据类型,只有值和地址都相同,比较才是true,否则都是false.
var obj1 = {name:"张三",age:20};
var obj2 = obj1;
console.log(obj2===obj1); //true 让两者值一样,在内存里地址也一样,就是传址;
- 传值 赋值 不会相互影响;
var a = 10;
var b = a; // var b = 10;
var b = 30;
console.log(a,b);// 10 30
2.传址(引用 ) :赋值会互相影响
var a = {
name:"张三",
age:20
}
var b = a;
a.age =30;
console.log(b);//{name: "张三", age: 30}
//明明改动的是a,但是b的也改了,
//因为他们用的地址是一样的,任意改动谁的值,另一个都会跟着改变。
传址问题如何解决 ??可以把对象或者数组拷贝一个一模一样的出来
一层对象
function copyObj(obj){
var newObj = {}; // 新开辟了一个内存地址
for(var key in obj){
newObj[key] = obj[key];
}
return newObj;
}
var obj = {
name:"张三",
age:20
}
var obj1 =copyObj(obj); //新生成了一个对象 ,那么这个对象就是一个新的内存地址
obj1.age = 30; //把obj1里的东西改成30
console.log(obj); // {name: "张三", age: 20}
//说明obj和obj1两者不是一个地址
function copyObj(obj){
var newObj = {}; // 新开辟了一个内存地址
for(var key in obj){
newObj[key] = obj[key];
}
return newObj;
}
var obj = {
name:"张三",
age:20
}
var obj1 = obj;
obj1.age = 30; //把obj1里的东西改成30
console.log(obj); // {name: "张三", age: 30}
//说明obj和obj1两者是一个地址
多层对象 深拷贝
function copyObj(obj){
var newObj = Array.isArray(obj)?[]:{}; // 新开辟了一个内存地址
for(var key in obj){ //这个循环既可以循环数组也可以循环对象;
if(typeof obj[key] === "object"){
newObj[key] = copyObj[key];
}else{
newObj[key] = obj[key];
}
}
return newObj;
}
// var obj = {name:"张三",age:20};
// var arr1 = copyObj(obj);
// console.log(arr1);// {name:"张三",age:20} 传入的是对象
var arr = [1,2,3];
var arr1 = copyObj(arr);
console.log(arr1);//(3)[1,2,3] 传入的是数组
如果需要把数组和对象区分开来处理
推荐一个方法判断一个值是不是数组 var res = Array.isArray(值);
如果值是数组就会返还 true,否则就会返还false
var res = Array.isArray({}); console.log(res);//false
总结:简单数据类型会传值,复杂数据类型会传址(但是会出现引用问题,相互之间会影响)
开发的时候多数情况下是不需要引用的,如果需要引用如何解决,通过深拷贝
(在内存里新开辟一个地址然后把之前的对象或者数组里的东西复制一份)。