大家都知道变量分为基本类型和引用类型,这边笔记主要介绍两种类型的变量赋值区别和在函数中变量的值传递相关的。 将基本类型变量赋予变量时,是把值赋值给了变量。将引用类型的值赋值给变量时,其实是变量里存储的是引用类型的变量地址
一,变量的复制
1. 基本类型变量复制
基本类型变量复制时,其实复制的是值,复制后变量和之前的变量没有任何关系。我们来个例子:
var num1 = 5
var num2 =num1
如下图的展示了复制过程:
2. 引用类型变量复制
引用类型的变量复制是地址的复制,而我们修改变量属性时,是在值本身做的修改,所以复制后,两个变量任何一个改变时,另外一个就会改变。例子:
var obj1=new Object()
var obj2=obj1
obj1.name="lili"
console.log(obj2.name) // lili
因为引用类型变量赋值的过程是将变量的引用地址赋值给了变量,而不是变量值。变量值存在对空间中,所以在复制时就会将变量的引用地址复制给另一个变量
有图可知,obj1和obj2复制时,只是复制了地址,他们还是指向同一个值,所以当改变obj1的值时,obj2的值也同时发生了改变
二、函数传值参数
在javascript里所有函数传值都是按值传递的,传参时,其实是将传入的参数复制给函数内部的局部变量(就是argument对象的一个属性)。 所以虽然是按值传递的,但是如果传递的引用类型,那么函数内接收到变量和函数外接收的变量会相互影响(这里经常会有一个面试题)
1,基本类型在函数中传值
基于函数参数是按值传递的,所以基本类型的参数,在函数内外互不影响
var name="a";
function setName(name){
name="b"
console.log(name) //b
}
setName(name)
console.log(name) //a
2,引用类型的传参问题
var obj1={name:'a'};
function setName(obj){
obj.name="b"
console.log(obj.name) //b
}
setName(obj1)
console.log(obj1.name) //b
如上例子:当将obj1传参给函数时,函数内部变量obj就复制了obj1的值,由于obj1存的值是对象的地址,所以内部变量obj拿到的是obj1的地址。 当修改内部obj时就修改obj1的值。 这里常见一个面试题如下:
var obj1={name:'a'};
function setName(obj){
obj.name="b"
obj={name:'c'}
console.log(obj.name)
}
setName(obj1)
console.log(obj1.name)
这个面试题,第一个打印是c,函数外的打印是b,是因为在函数内对obj=新的对象时,就已经相当于重新建了一个对象,obj已经指向了新的对象,所以obj和obj1已经不再指向同一个对象。