javascript 中的奇怪示例,为什么我不能通过函数参数重新分配全局变量的值?

Weird examples in javascript, why I can't reassign a global variable's value through a function's parameter?

谁能帮我解释一下下面三个例子的原理(困扰了我很久,google找不到答案)?为什么它们会产生完全不同的结果?

示例 1。 我创建了一个名为 myArray 的全局变量,并直接用函数更改了它的值。一切都在按预期进行。我更改了 'myArray'.

的值
var myArray = [1, 2, 3, 4, 5];

function alterArray(){
  myArray = [5, 4, 3, 2, 1]
  return myArray; 
}

alterArray();
console.log(myArray);  //-> Array(5)[ 5, 4, 3, 2, 1 ]

示例 2。 为了使 alterArray 函数更高效,我为其添加了一个参数,以便该函数可以将任何全局变量更改为数组 [5, 4, 3, 2, 1]。那么这个功能就不起作用了。 myArray 仍然是 [1, 2, 3, 4, 5]。为什么?发生了什么?

var myArray = [1, 2, 3, 4, 5];

function alterArray(arr){
  arr = [5, 4, 3, 2, 1];
  return arr;
}

alterArray(myArray);
console.log(myArray); //--> Array(5)[ 1, 2, 3, 4, 5 ]

示例 3。 我把函数中的arr = [5, 4, 3, 2, 1];改成了arr[0] = "number one";(灵感来自第4章的练习EloquentJavascript)。该功能再次起作用!为什么?为什么当我通过参数为 myArray 分配一个完整的新值时该函数不起作用,但当我通过参数仅更改 myArray 的一部分时该函数运行良好?

var myArray = [1, 2, 3, 4, 5];

function alterArray(arr){
  arr[0] = "number one";
  return arr;
}

alterArray(myArray);
console.log(myArray); //--> Array(5)[ number one, 2, 3, 4, 5 ]

首先你要明白scope

  1. 在任何函数外部声明的变量具有全局作用域,可以从文件中的任何位置访问。
  2. 当一个变量在函数内声明时,它是函数作用域的,这意味着它只能在函数内访问。
  3. 在 JavaScript 中声明为 var x 的 ES5 变量遵循以上 2 条规则。在 JavaScript ES6 中,您还可以将变量声明为 let x = 5const x = 5,这些声明是块作用域的,这意味着它们只能在块内访问(例如 if 块)

进入正题。

当您将变量作为参数传递时

var x = 5;
change (x){ // here you've passed the value of x to the function, value of x is copied to new variable x inside the function.
  x = 3; // this x is not the same as above declared x
}
 change (x);
//In this example you've declared a new variable called x and initialised it with the value of global x.  
//So when you're assigning 3 to the `x` in line `x=3` you're changing the value of local variable, not the global.

在您的第一个示例中,您没有将全局数组的值复制到新数组,而是直接更改它的值。

找到变量后,JS 解释器会在本地上下文中查找它的定义,在本例中是在函数内部。如果它没有找到它的定义,它会转到上层(全局层)。在这种情况下,解释器已经在函数内部找到了 x 的定义,因此它没有寻找全局声明并更改了局部变量。

var x = 5;
change();
  x = 3; // here I haven't passed it as argument, so this x is not a copy of global x, it is the original global x
}
// The interpreter looked for definition of x inside the function, it didn't find. So it looked for global declaration and found it and finally changed the global variable

第三种方法是将变量作为参数传递并更改它。它并不像听起来那么完整。

var x = 5; //global declaration
change(x){ //remember this x is different then the above. Now this x holds 5, as the value of global variable x is copied into it.
  x = 3; // now we changed the local variable
  return x; // the function is returning the value of x to the caller. So we need to collect the returned value when we call the function
}

//call the function
x = change(x); // same as x = change(5)
// Here global value got copied to the local variable and it got changed inside the function. The changed value was returned back.
// so we collected the changed value with x = function call