传递给函数的数组不会变异?

Joh*_*ant 0 javascript arrays pass-by-reference

我认为Arrays是对象所以当我执行这行代码时,我期待得到[3,3,3]因为我改变了数组.但是我得到了[2,4,6]

var arr = [2,4,6];

function checkArr(arr){
    arr = [3,3,3];
}

console.log(arr)
Run Code Online (Sandbox Code Playgroud)

如果我添加一个return语句,那么我得到了我期望的值.我想知道为什么在执行函数期间给arr一个新值时需要返回.

var arr = [2,4,6];

function checkArr(arr){
    arr = [3,3,3];
  return arr;
}

console.log(arr)
Run Code Online (Sandbox Code Playgroud)

最后,在这个for循环中我不使用,return并且数组值被更改!我有点困惑.为什么第一个例子没有改变值arr

var arr = [2,4,6];

function checkArr(arr){
    for(var i = 0; i<arr.length; i++){
    arr[i] = 3
  }
}

console.log(arr)
Run Code Online (Sandbox Code Playgroud)

Pin*_*eda 5

您没有测试示例中的pass-by-reference和pass-by-value之间的区别.您实际上正在测试变量范围.

对于关于Javascript按值传递VS传递引用的问题的一个很好的答案,这里已经是堆栈上的答案.


您的代码示例的行为的说明

在函数内声明(创建)的变量是该函数的本地变量.这适用于var使用函数内的关键字声明的任何变量以及函数采用的任何参数.

在函数内部声明的变量可以在函数内部访问,如果它没有得到一个由同一名称声明的变量.


例1:

var arr = [2,4,6]; ------------------
                                     |
function checkArr(arr){              |
// paramter means that a local       |
// variable 'arr' created inside     |
// function, so refers to value      |
// passed as argument or undefined   |
                                     |
  arr = [3,3,3];                     |
}                                    |---- you're loggin this variable, 
                                     |     the one inside the funciton is
var check = checkArr(arr);           |
                                     |     function and eny enclosing child functions
console.log(arr)  <------------------      (for the life of the function)
Run Code Online (Sandbox Code Playgroud)

如果我们将参数名称更改为其他名称,则行为会变得更加明显:

var arr = [2,4,6];

function checkArr(ref){
  ref = [3,3,3];
}

checkArr(arr);
Run Code Online (Sandbox Code Playgroud)

调用该函数时,ref将创建一个本地值并将其设置为REFERENCE arr.接下来的行,然后用数组文字覆盖ref的值而不是实际值arr[3,3,3].

function checkArr(){
  var ref = REFERENCE_TO_ARRAY_PASSED_IN;

  ref = [3,3,3];  // REFERENCE to 'arr' OVERWRITTEN by Array  literal
                  // global 'arr' remains unaffected
}
Run Code Online (Sandbox Code Playgroud)

例2:

var arr = [2,4,6];

function checkArr(arr){
    arr = [3,3,3];
  return arr;
}

console.log(arr);
// this should log out [2, 4, 6] since you're not even invoking checkArr...
Run Code Online (Sandbox Code Playgroud)

例3:

var arr = [2,4,6];

function checkArr(arr){
  // same as first example
  // a local variable 'arr' is created
  // from the parameter 'arr'

  // this for loop won't even run
  // if 'arr' isn't passed in as an argument
  // it'll fail on the first condition
  for(var i = 0; i<arr.length; i++){
    arr[i] = 3
  }
}
// the arr variable INSIDE the function is not available here

console.log(arr) // logs out [2, 4, 6]
// this function refers to the variable declared above the function definition, again you haven't even invoked the funciton 'checkArr'
// thought even if you did, it would not change the console.lout ouptput
Run Code Online (Sandbox Code Playgroud)

获取影响全局变量的函数:

从函数定义中删除参数

var arr = [2,4,6];

function checkArr(){
  // no local variable or parameter is defined here
  // but function has access to it's enclosing scope
  // where there IS a variable 'arr'
  arr = [3,3,3]
}

var check = checkArr();

console.log(arr);

// logs out [3,3,3]
Run Code Online (Sandbox Code Playgroud)

当现在调用该函数时,您将改变该数组,因为该函数将在本地查找变量'arr',当它找不到它时它将查看它的封闭范围,在这种情况下是全局范围它会找到变量arr并改变它.