javascript - 关于函数传参的疑问
迷茫
迷茫 2017-04-11 12:12:20
[JavaScript讨论组]

函数传参数是传引用,为什么下面这样赋值不起作用?

var a = [1,2,3]
function fn(arr){
  arr = a
}
var b = []
funcArr(b)
b   //  []

当遍历就可以

var a = [1,2,3]

function fn(arr){
  for(var i in a){
      arr[i] = a [i]
  }
}
var b = []
funcArr(b)
b   // [1,2,3]

这意味着我不能改变b?可以直接赋值
var a = [1,2,3]

function fn(){
  b = a
}
var b = []
funcArr(b)
b   // [1,2,3]

但是通过传参数b就不能赋值但是可以改变b的key来改变b

function fn(arr){
  arr.push[1]
}
var b = []
funcArr(b)
b   //  [1]

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(2)
高洛峰

你搞错了一个概念,就是ECMAScript中所有的函数传参都是按值传递的。
1.对于基本类型,都知道是按值传递的(把值从一个变量复制到另一个变量)。
2.对于引用类型,在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量。来看一个例子:

function setName(obj) {
        obj.name = "Sun";
        obj = new Object();
        obj.name = "Moon";
 }
 var person = new Object();
 setName(person);
 console.log(person.name)    //"Sun"

这个例子最后的打印结果是"Sun",而不是"Moon"。
分析一下:

  新创建的对象作为参数传给setName();此时传的是Object在内存中的一个地址,将这个地址复制给了参数 obj,然后通过obj给Object添加了一个值为"Sun"的name属性,下一行又新建了一个Object,并将其地址赋值给了obj,此时的obj指向的是新的Object,切断了与传进来的对象的联系,并添加了"Moon"的"name"属性。如果person是按引用传递的,那么最后的结果必然是"Moon"。这说明即使在函数内部修改了参数的值,但是原始的引用仍然没变。

了解了参数是按值传递的,现在回到你的问题上,你将b作为参数传给function,然后再function内部重新给参数arr赋值为a,b并没有任何变化,所以还是原来的定义的空的数组。

大家讲道理

Java/C#/JavaScript 这些语言里提到的引用,并不是 C++ 里面那个引用的概念,对应于 C++ 中的 const 指针可能更贴近一些,所以它并不能从函数里通过赋值来改变实参的值。

你提到的“遍历可以”,是因为你在函数里改变的不是形参,而是形参所引用的对象的属性。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号