函数入参的传递

// [1]
var arr = [1, 2]
function change(arr) {
  arr = [1, 2, 3]
}
change(arr)
console.log(arr) // => [1, 2]
// [2]
var arr = [1, 2]
function change(arr) {
  arr.push(3)
}
change(arr)
console.log(arr) // => [1, 2, 3]

按照《JavaScript 高级程序设计》中的说法:

基本类型值的传递如同基本类型变量的复制一样。引用类型值的传递则如同应用类型变量的一样

为什么赋值不会改变外部 arr,而 push 方法则会改变外部 arr 的值呢?


友情链接:
[sof] Is JavaScript a pass-by-reference or pass-by-value language?

阅读 2k
3 个回答

在调用函数change的时候,change这个函数的作用域内会有一个新的变量arr,这个arr全局的arr都指向同一个内存地址,即存储数组[1, 2]的内存地址。

代码段一执行arr = [1, 2, 3],也就是在内存中存储一个新的数组[1, 2, 3],然后把这个数组的内存地址赋值给arr,注意这个arrchange函数内的变量,所以这个arr指向数组[1, 2, 3]的内存地址,而全局的arr仍然指向[1, 2]的内存地址。注意[1, 2, 3]是一个新的数组,所以需要一个新的内存空间。

代码段二执行arr.push(3),首先会找到arr指向的数组,也就是[1, 2],然后往这个数组中添加数据3,因为change函数内的arr全局的arr指向的是同一个内存地址,而这个地址指向的内容已经改变了。

arr相当一个地址的容器 " arr = [1, 2, 3] "只不过是把新的"[1, 2, 3]"数组的地址放进arr中, 把原来的地址覆盖了, 原来的数组还是存在原来的地方

var arr = [1, 2]
生成了2块空间
内存A: 存放数组的实例 [1, 2]
内存B: 存放"A"的地址 名称叫 "arr"

arr = [1, 2, 3]
生成了1块空间
内存C: 存放数组的实例 [1, 2, 3]
并把 "B"的内容从"A"的地址改成"C"的地址

这个赋值只影响了"B"的值, 并不影响"A"

arr.push(3)
是通过arr 也就是"B"里面的内容, 找到"A"并往里面放了个值, 真正修改到了原来的数组

有参函数实际上有一个隐式的变量声明,第一函数,改变的是局部变量的指向地址。第二个函数中局部变量指向和全局变量是同一个地址对象,所以结果不一样。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题