将全局变量传递给函数

Ema*_*gux 12 javascript scope

为什么以下代码给我0而不是1?我希望我的函数更改在函数外声明的变量,但我不想在函数声明中指定变量.

that = 0;

function go(input) {
    input++;
}

go(that);

console.log(that);
Run Code Online (Sandbox Code Playgroud)

Phi*_*l-R 13

正如Oriol所回答的,它不起作用,因为变量是按值传递的,所以你不会改变"那个"变量.解决方法是传递变量名称:

that = 0;

function test(input) {
    window[input]++;
}

test("that");

console.log(that); // 1
Run Code Online (Sandbox Code Playgroud)


Ori*_*iol 9

那是因为你是按值传递变量,而不是通过引用.

在javascript中,所有变量都是按值传递的,除了通过引用传递的对象(实际上,它们也是通过值传递但它们是引用,见下文).

你无法改变这种行为.

编辑:如果您不知道通过值/引用传递的是什么,您应该阅读教程.但是这里有一些例子:

  • 变量按值传递

    function foo(bar){
       console.log(bar); // 1
       bar++;
       console.log(bar); // 2
    }
    var mybar = 1;
    console.log(mybar); // 1
    foo(mybar);
    console.log(mybar); // 1
    
    Run Code Online (Sandbox Code Playgroud)
  • 变量传递(值但用作)参考

    function foo(bar){
       console.log(bar.a); // 'b'
       bar.a = 'c';
       console.log(bar.a); // 'c'
    }
    var mybar = {a:'b'};
    console.log(mybar.a); // 'b'
    foo(mybar);
    console.log(mybar.a); // 'c'
    
    Run Code Online (Sandbox Code Playgroud)

在你的情况下

你可以做

  • 使你的变量成为一个对象的属性(在你的情况下,因为它是一个全局变量,使用window)并传递对象(引用),所以你可以改变它

    window.that = 0;
    function go(obj) {
        obj.that++;
    }
    go(window);
    console.log(that); // 1
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用返回值

    var that = 0;
    function go(input) {
        return input++;
    }
    that = go(that);
    console.log(that); // 1
    
    Run Code Online (Sandbox Code Playgroud)

请注意,你做不到

  • 将变量转换为对象

    var that = new Number(0); // Now it's an object number
    function go(input) {
        input++;
    }
    go(that);
    that *= 1; // Now it's a literal number
    console.log(that); // 0
    
    Run Code Online (Sandbox Code Playgroud)

    那是因为对象也是按值传递的,但它们是一个引用.这意味着在函数内部可以更改外部对象的属性(因为它是引用),但是您无法更改整个对象,因为它是按值传递的.

    请参阅此处的示例:https://stackoverflow.com/a/3638034/1529630