【问题标题】:Passing global variable by reference and modifying the referenced variable通过引用传递全局变量并修改引用的变量
【发布时间】:2012-03-16 13:09:15
【问题描述】:

正确的做法是什么...

var array1 = []
var array2 = []

function doIt(arg){
    var myArray;

    if(arg == 1){
        myArray = array1
    }else if(arg == 2){
        myArray = array2
    }

    myArray.push('test');

}

doIt(1); //array1 should now be ['test'] but it's empty

【问题讨论】:

  • “它是空的”到底是什么意思?顺便说一句,您缺少一些分号。
  • @AdamBernier:JavaScript 不是插入有用的自动分号以使程序员的生活更轻松吗?另外,我假设“空”的 OP 意味着 array1 不包含任何元素(这是因为 myArray = array 制作了数组的 copy )。
  • @Kerrek SB:你可能是对的;一些开发环境可能会自动插入分号。关于您的第二点:数组是对象并且通过引用传递。
  • Javascript 不通过引用传递。和 Java 一样,对象隐藏在引用后面,它们是按值传递的
  • @ofko - 我认为问题中的代码没有任何问题,只是如果您使用 1 或 2 以外的值调用函数会出现错误(在这种情况下,它会尝试做undefined.push())。但是对于 1 的值,它应该可以按您的预期工作。是否有任何其他未显示的代码可能会影响它?

标签: javascript pass-by-reference


【解决方案1】:

除了四个小的语法缺陷之外,您的代码还可以:http://jsfiddle.net/hk9Md/

var array1 = []; // <-- added semi-colon
var array2 = []; // <-- added semi-colon

function doIt(arg){
    var myArray;

    if (arg == 1) {
        myArray = array1; // <-- added semi-colon
    } else if (arg == 2) {
        myArray = array2; // <-- added semi-colon
    }
    myArray.push('test');
}
doIt(1);
alert(array1[0]); // produces 'test' 

【讨论】:

  • 那些“缺失”的分号都是可选的。我更喜欢将它们作为一种风格包含在内,但是无论有没有它们,这个特定的代码都会完全一样地工作。 (我承认有有个包含分号的情况,但事实并非如此。)
  • @nnnnnn:这很有趣,谢谢。感谢 Kerrek SB 在其他 cmets 中也提到了这一点。
  • 我发现我的代码为arg 传递了错误的值,这就是问题所在。无论如何,我希望这对某人有所帮助。
【解决方案2】:

为什么不:

var myArray = arg == 1? array1 : array2;

如果有两个以上的选择,你可以试试:

var source = {
  '1': array1,
  '2': array2,
  '3': array3,
  ...
}

或零索引:

var source = [ ,array1, array2, array3, ...];

然后:

function doIt(arg) {
  var myArray = source[arg];
  ...
}  

甚至:

var doIt = (function() {
  var source = {
    '1': array1,
    '2': array2,
    '3': array3,
    ...
  }
  return function (arg) {
    var myArray = source[arg];
  }
}());

填满你的靴子。 :-)

【讨论】:

  • 好的,它们都是实现问题的其他方式,但为什么原始代码不能按原样工作?
【解决方案3】:

可以说,做到这一点的“正确”方法不是编写具有副作用的函数。您可以编写函数,使其返回数组的修改副本:

var array1 = [1, 2, 3],
    array2 = [4, 5, 6],
    x = getUserInput(),
    result = doIt(1, x == 1 ? array1 : array2);

function doIt(arg, original_array){
  var copy = [].concat(original_array);
  // ...
  return copy;
}

有时这是不可避免的,但当局部函数更改全局状态时,程序会变得更难调试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    相关资源
    最近更新 更多