Javascript 是不是通过引用或值将数组传递给函数?
Posted
技术标签:
【中文标题】Javascript 是不是通过引用或值将数组传递给函数?【英文标题】:Does Javascript pass array to function by reference or value?Javascript 是否通过引用或值将数组传递给函数? 【发布时间】:2016-06-19 00:20:48 【问题描述】:据我了解,javascript 通过引用传递对象,而数组也是一个对象,但是当我创建一个整数数组然后将其传递给函数时,如下代码:
function testFunc(outTestArray)
var aiTemp = [1,2,3,4];
/*Using slice(0) to clone array */
outTestArray = aiTemp.slice(0);
var aiTest = Array.apply(null, Array(4)).map(Number.prototype.valueOf, 0);
testFunc(aiTest);
console.log(aiTest.toString()); // aiTest still [0,0,0,0]
我也知道 slice(0) 函数只返回一个数组的浅拷贝,但如果数组只是一个整数数组。所以我的问题是为什么不修改aiTest的数据?
【问题讨论】:
***.com/questions/518000/… 重复。简短回答:Javascript 总是按值传递,数组/对象除外。 JavaScript 总是按值(复制)。但是,对于对象,值是一个引用(按值引用)。 Is JavaScript a pass-by-reference or pass-by-value language? 你所期望的是一个指针,其中outTestArray
引用了aiTest
,这是 JavaScript 所没有的。
我认为问题出在 slice(0) 函数上。因为如果在函数 testFunc() 我修改如下: outTestArray[0] = 1; outTestArray[1] = 2;...然后将aiTest传递给这个函数,aiTest就会改变。
@TrungNguyen 问题是=
。通过分配outTestArray
,您可以修改它的值。但是,aiTest
仍然指的是原始数组。 outTestArray[1] = 2
行为不同的原因是因为它修改了数组本身而不是修改任何一个变量。
【参考方案1】:
函数参数就像新的变量赋值,它不像 C 中的引用或指针。更像是这样:
function testFunc(...args)
var outTestArray = args[0];
var aiTemp = [1,2,3,4];
/*Using slice(0) to clone array */
outTestArray = aiTemp.slice(0);
...
如您所见,在上面的代码中,您正在克隆数组并将其分配给函数范围内的变量outTestArray
,该变量在函数外部无法访问。
你可以使用闭包来实现你想要的:
var outerArray;
function testFunc(array)
var aiTemp = [1,2,3,4];
outerArray= aiTemp.slice(0);
甚至更好,只返回一个新数组:
function getArray()
return [1,2,3,4];
var aiTest = getArray();
...
【讨论】:
【参考方案2】:在您的代码中,testFunc
获取对复制到参数outTestArray
中的原始数组的引用。在函数体中,您使 outTestArray
指向不同的数组。如果你想改变原来的数组,那么你可以说
outTestArray.splice(0, outTestArray.length, ...aiTemp)
请注意,扩展运算符用于aiTemp
。
【讨论】:
【参考方案3】:你的错误在于你对浅拷贝的概念是错误的。
浅拷贝复制数组的内容,但不复制数组成员引用的东西。
如果您的数组是对对象的引用数组,则浅拷贝将复制引用,因此您的新数组将指向相同的底层对象。
但是这个数组是整数。整数本身被浅拷贝复制。
【讨论】:
正如你所说的“整数本身被浅拷贝复制。”是的,我知道这一点。但这与为什么aiTest在out of function后没有变化无关? 数组通过引用副本传递。 testFunc 的 outTestArray 是对底层数组的引用。您的 aiTemp 分配将该 reference 设置为指向新数组 [1,2,3,4]。然后你出于某种原因复制它。您不是在修改引用后面的数组,而是在修改 reference 本身 明确地说,你可以通过改变底层数组来修改它,比如outTestArray[0] = 1
。这将修改您的aiTest
的第一个值。
所以:赋值修改引用。对象通过复制引用传递。但是您仍然可以通过调用更新其状态的函数或其他方式来改变对象。以上是关于Javascript 是不是通过引用或值将数组传递给函数?的主要内容,如果未能解决你的问题,请参考以下文章