定义:所有函数的参数都是按值传递的,这意味着函数外的值被会被赋值到函数内部的参数中,就像从一个变量赋值到另外一个变量一样
**原始值:那么久跟原始值变量的复制一样**
**引用值:那么久跟引用值复制一样**
变量有按值和按引用访问,而传参只有按值传递
在按值传递参数时,值会被复制到一个局部变量(即一个命名参数,或者用ECMAScript的话说,就是arguments
对象中的一个槽位),在按引用传递参数时,只在内存中的位置会被保存在一个局部变量,这意味着对本地的变量的修改会反映到函数外部(这在ECMASript中是不可能的)
例子1:值传递
function addTen(num) {num += 10return num}let count = 20let res = addTen(count)console.log(count); // 20console.log(res); //30
相当于: let num = count
上面的例子幂函数addTen中有一个参数num,它其实是一个局部变量
,在调用的时候,变量count作为参数传入,count的值是20,这个值被复制到参数num以便在addTen()内部使用,在函数内部,参数num的值被加上了10,但是这并不会影响到原始的变量count,参数num和变量count互不干扰。他们不过碰巧保存了一样的值。
例子2:引用传递
function setName(obj) {obj.name = 'nike'}let person = new Object()setName(person)console.log(person.name); //nike
这一次,我们吧一个对象保存在变量person中,然后这个对象被传给setName,在函数内部,obj和person都指向同一个对象。结果就是,即使对象是按值传递进函数,obj也会用过引用访问对象,在函数内部给obj设置属性是,函数外部对象也会发生变化。因为obj指向的对象保存在全局作用域的堆内存上面
,所以我们大多数会认为局部作用中修改对象发生变化反映到全局,这就意味着参数是按引用传递,那么我们在看下面一个例子
function setName(obj) {obj.name = 'nike'obj = new Object()obj.name = 'Greg'}let person = new Object()setName(person)console.log(person.name); //nike
我们将obj重新定义为一个有着不同name的新对象,如果person是按引用传递,person应该自动将指针知道新的对象,但是我们再次访问person的时候,还是nike,这表明:当obj在函数内部重写的时候,它变成了一个指向本地对象的指针,而那个本地对象在函数执行结束后就被销毁了
注意:ECMASript中函数的参数就是局部变量
简单点总结来说:函数传参就好像是把传递的参数直接赋值给了函数调用中的变量