【问题标题】:Change global variable inside JavaScript closure更改 JavaScript 闭包内的全局变量
【发布时间】:2012-11-21 06:14:17
【问题描述】:

我正在尝试更改闭包中变量的值:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        myVariable = data;
    }
});

这不起作用,因为myVariable 对闭包不可见。如何更改此代码以使myVariable 的值发生变化?

【问题讨论】:

  • 这不是真的。根据定义,如果它是全局的,那么它可以在所有范围内访问。当然,如果有一个名为myVariable的局部变量,那么它将被修改而不是全局版本。如果它真的是全球性的,您可以通过window.myVariable 访问它。
  • 您的示例没有说明为什么它在成功回调的范围内不可见。唯一可以隐藏它的是在更近的范围内有一个同名的变量会隐藏它。
  • 嗯,我认为变量没有改变,因为 ajax 不是同步的。不知道如何使它同步
  • @user1811367:不要。了解如何使用回调。
  • myVariable is 已更新(在 Firebug 中查看以查看)。但不是在你认为应该的时候。看看我的回答。

标签: javascript closures


【解决方案1】:

与您的看法相反,您的代码有效。但是看到你正在尝试做的事情并在字里行间阅读我猜你正在尝试这样做:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        myVariable = data;
    }
});
alert(myVariable); // at this point myVariable is undefined!!

如果是这样,您需要了解异步函数。

基本上,$.ajax() 函数在实际提交 ajax 请求之前返回。当浏览器不忙于执行 javascript 时,它将稍后执行 ajax 请求。这意味着当您尝试提醒myVariable 的值时,分配还没有发生。

在此处阅读我的回复以获取更多详细信息:JS global variable not being set on first iteration

唯一好的解决方案是改变您对编码的看法。 (有一个可以说是糟糕的解决方案,涉及将 ajax 调用转换为同步,但我们不要介入,如果需要或阅读手册,您可以谷歌搜索)。而不是这样做:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        myVariable = data;
    }
});
/*
 * Do lots of stuff with the returned value
 * of the myVariable variable
 *
 */

你现在需要这样写:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        myVariable = data;
        /*
         * Do lots of stuff with the returned value
         * of the myVariable variable
         *
         */
    }
});

基本上将您在 ajax 调用之后编写的所有代码都移动到成功回调中。这需要习惯(从互联网上有多少这个问题的变体来判断)。但是一旦你习惯了它就会成为第二天性。

这种编程风格有一个名字。它被称为:“事件驱动编程”“连续传递风格”“事件驱动编程”。如果您想了解更多信息,可以搜索各种术语。

【讨论】:

  • 这很可能是问题的核心,尽管根据解释很难说清楚。
  • @tjameson:根据我的经验,每当有人试图将回调的结果分配给封闭的变量时,很可能就是问题所在。回答问题的时间足够长,你就会看到问题的规律。
【解决方案2】:

如果该代码在全局范围内,则 myVariable 对内部函数可见。如果您担心它被局部变量遮蔽,请将其作为全局属性显式访问:

var myVariable;
$.ajax({
    //stuff....
    success:function(data) {
        window.myVariable = data;
    }
});

【讨论】:

    猜你喜欢
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 2015-11-24
    • 2011-09-30
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多