17

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

that = 0;

function go(input) {
    input++;
}

go(that);

console.log(that);
4

5 回答 5

20

正如 Oriol 所回答的那样,它不起作用,因为变量是按值传递的,所以您没有更改“那个”变量。一种解决方法是传递变量名称:

that = 0;

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

test("that");

console.log(that); // 1
于 2013-08-12T02:28:24.757 回答
17

那是因为您是按值传递变量,而不是按引用传递。

在 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
    
  • 通过(值但用作)引用传递的变量

    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'
    

在你的情况下

你可以做

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

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

    var that = 0;
    function go(input) {
        return input++;
    }
    that = go(that);
    console.log(that); // 1
    

请注意,您不能这样做

  • 将变量转换为对象

    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
    

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

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

于 2013-08-12T02:22:56.560 回答
3

这与指针、范围、通过引用传递变量以及所有这些爵士乐有关。

如果你真的想这样做,你可以像这样在 Javascript 中传递一个对象:

var that = {value: 0};
function go(input) {
    input.value++;
}
go(that);
console.log(that.value);

我们所做的只是将一个对象定义为在 Javascript 中作为引用传递。然后我们只需确保我们正确地修改了对象的属性。

于 2013-08-12T02:26:47.080 回答
1

你的代码

那= 0; //全局变量

function go(input) { //输入是参数,不通过引用传递
    输入++;//这只是增加一个本地副本,即0
}

去(那个);//通过 0

控制台.log(那个);

而是这样做

那= 0;

函数去(){
    那个++;
}

去(); //不传递任何变量..函数已经可以看到全局“that”

控制台.log(那个);// 这将打印 gloabl 即 1

于 2013-08-12T02:29:34.057 回答
-4

实际上,您可以console.log(input)在函数内部添加它,它会工作得很好。

如果我错了,请纠正我。希望我有帮助!

如果有人能解释为什么我错了,我会很高兴

于 2019-12-13T11:44:40.250 回答