【问题标题】:In javascript, array is showing 'pass by value' behavior instead of 'pass by reference'在 javascript 中,数组显示“按值传递”行为而不是“按引用传递”
【发布时间】:2019-09-30 13:25:48
【问题描述】:

我知道数组是 javascript 中的对象,使其成为非原始数据类型,默认情况下使其成为按引用传递。 现在,在我遇到的大多数用例中都是如此,但是我分享的代码显示了一种我不理解的奇怪行为,它看起来更像是“按值类型传递”。

var arr = ['a','b','c']
/*
function addArr(ar){
    ar.push('d')
    return ar
}

console.log(addArr(arr))  // ['a', 'b', 'c', 'd']
console.log(arr)          // ['a', 'b', 'c', 'd']
*/

//the above output is expected behavior for an Array object



function changeArr(ar){

    console.log(ar)   //1-// ['a', 'b', 'c']
    ar = ['12','11']
    console.log(ar)   //2-// ['12', '11']
    return ar
}

console.log(changeArr(arr)) //3-// ['12', '11']
console.log(arr)            //4-// ['a', 'b', 'c']

//now I expect the forth console output to be  ['12','11'] here because it is an object

【问题讨论】:

  • 您已经为引用分配了一个新数组,使其成为一个新对象。
  • JavaScript 总是按值传递。但是,对象的 是它的引用。不过,如果您重新分配 变量,则不会更改 引用末尾的对象

标签: javascript arrays pass-by-reference pass-by-value primitive-types


【解决方案1】:

您基本上是在重新分配对象而不是修改原始对象。

ar = ['12','11']

这就是 Javascript 重新分配新值的原因。

【讨论】:

    【解决方案2】:

    请查看 cmets。

    let arr = [1, 2, 3, 4];
    
    function changeArr(ar) {
    
      //console.log(ar)
      ar = ['12', '11'] // creating a new array ie creating a new space in heap putting these values there and storing its reference in ar or assigning it to the reference 
      //console.log(ar)
      return ar
    }
    
    function changeArr2(ar) {
    
    
      ar.push(55); // here we have changed the array  that is pointed by the reference stored in ar
    
      return ar
    }
    
    console.log(changeArr(arr))
    console.log(changeArr2(arr));
    console.log(arr) // now the original array contains 55 too

    更清晰的图片看这里-https://stackoverflow.com/a/57852144/7849549

    【讨论】:

      【解决方案3】:
      function changeArr(ar){
      
          console.log(ar)
          ar = ['12','11'] // <- THIS LINE RIGHT HERE
          console.log(ar)
          return ar
      }
      

      您正在创建一个新数组,而不是操作旧数组。每次调用该函数时,您都会创建一个新数组并返回新数组(如果您调用该函数 5 次,您将获得 5 个新数组)。您作为输入传递的那个无关紧要,保持不变。

      EDIT 您创建的新数组与作为输入传递的数组之间的唯一关系是它们在闭包内使用相同的变量名,因此,在该闭包内,您不能再同时访问输入和新数组。但这是一个不同的话题......

      也许这样会更清楚:

      var x = 'something that is not an array'
      console.log(changeArr(x));
      console.log(x);
      

      这也许会更清楚:

      var arr = [1,2,3,4];
      console.log(changeArr());
      console.log(arr);
      

      【讨论】:

      • 好的,这确实很清楚,所以我在函数内部创建了一个与函数参数无关的新数组,因此两个对象都不同,但是我从未在函数内部声明 ar。我的意思是 changeArr 函数内部应该有某种声明,例如 'var ar = ["12", "11"] ',以表明这不是同一个数组。尽管代码的行为方式相同,即使我使用 'var ar = ["12","11"]' 或 'ar = ["12", "11"]'
      • 您不需要指定 var 关键字来声明某些内容。打开您的控制台并输入ar = ['12','11']。其次,variable shadowing。该死的电脑,它们总是完全按照你告诉它们做的,而不是你想让它们做的:)
      猜你喜欢
      • 1970-01-01
      • 2015-11-11
      • 2021-06-01
      • 2013-02-09
      相关资源
      最近更新 更多