【问题标题】:Javascript - can modify array passed to function only sometimesJavascript - 有时只能修改传递给函数的数组
【发布时间】:2015-07-10 21:54:39
【问题描述】:

为什么第一个函数不像第二个函数那样修改原始数组?

var a= [3, 4, 5];
function doesNothing(a) {
    a=[1,1,1];
}

function doesSomething(a) {
    a.push(6);
}

doesNothing(a);
console.log(a);     // [3,4,5] not [1,1,1]
doesSomething(a);
console.log(a);     //[3,4,5,6]

【问题讨论】:

  • 因为在 JS 中所有的东西都是按值传递的。参数a 是一个新值。和函数外的a不一样。

标签: javascript arrays reference


【解决方案1】:

在doesNothing() 内部,局部变量a 指向与外部变量a 相同的数组。然后将新创建的数组分配给本地a。

function doesNotNothing(a) {
  a[0] = 1;
  a[1] = 1;
  a[2] = 1;
}

这会影响数组元素的内容。

【讨论】:

    【解决方案2】:
    1. 如果a作为参数传入函数,它是一个局部变量,所以重置它的值不会影响外部变量a。
    2. 但是使用改变数组的方法会改变外部变量,比如 pop()/shift()/push/splice... 你也可以使用 '.'直接改变数组,如:arr.length=0;; push() 可以有多个参数,所以你可以:arr.push(...anotherArray)。
    3. 如果 a 没有作为参数传递,而是函数直接从全局作用域中读取,重置值会直接改变变量。 所以,直接在函数内部读取,不要作为参数传递。或者将其作为参数传递,但使用会改变数组以更改其值的方法。
    4. 查看示例: pass as a param

    read from outside directly

    【讨论】:

      【解决方案3】:

      因为在您的第一个函数中,a = 语句在局部范围内初始化了一个 new 变量(它本质上转换为 var a =)与全局 a 变量完全无关,而在第二个函数,你调用并改变传递给它的原始数组。

      【讨论】:

        【解决方案4】:

        第一个函数不尝试修改数组。它所做的只是为参数分配一个新值,当它被调用时,它被赋予了对数组的引用的副本。第一个函数中的变量a 只是一个以对象引用为值的变量。赋值语句只是改变了它的值,就像你的函数有

            a = 5;
        

        改为。

        请注意,您已使用 a 作为参数声明了第一个函数 - 符号 a 将 a 隐藏在函数之外。

        第二个函数确实修改了数组,因为它调用了修改它的数组对象上的方法。

        【讨论】:

          【解决方案5】:

          试试这个

          var a= [3, 4, 5];
          function doesNothing() {
              a=[1,1,1];
          }
          
          function doesSomething() {
              a.push(6);
          }
          
          doesNothing(a);
          console.log(a);    
          doesSomething(a);
          console.log(a);
          

          【讨论】:

          • 嗨 prashanth,OP 想知道为什么会发生这种情况,而不是如何解决
          • @Typo 我本来打算发布的,但其他答案中已经提到过
          猜你喜欢
          • 2020-09-11
          • 1970-01-01
          • 2019-10-19
          • 2020-11-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多