【问题标题】:How the variables are out of scope?变量如何超出范围?
【发布时间】:2013-10-26 22:15:02
【问题描述】:

我有以下 jquery 代码:

$.ajax({
    url: 'somefile.php',
    type: "POST",
    data: "",
    dataType: "json",
    async: false,
    success: function (data) {
                var var1  = something;
                var var2  = something;
                var var3  = something;
                var var4  = something;
                for (var i = 0; i < data.length; i++) {
                    $('.somediv').html('');
                    $('.somediv').append('Somehtml');
                }
                some_function_declared_later(var1, var2, var3, var4);
             }

编译时出现错误:'var1','var2','var3' &amp; 'var4' are used out of scope。但是,我认为没有问题,因为它们已在使用它们的同一函数中声明。

请帮忙!

更新: 这可能与当前函数之外的some_function_declared_later 的声明有关吗???

【问题讨论】:

  • “编译时出现错误” 正在编译?用什么?
  • 他们不是。它们在for 范围内定义。
  • @DavidHedlund:这是 JavaScript。 var总是在函数范围(或全局范围,如果在任何函数之外使用)创建变量。
  • 这些变量应该在范围内,因为 JS 具有函数级范围而不是块范围,尽管如果 data.length 恰好为 0,它们都将具有值 undefined。我会建议无论它是否在 JS 中工作,在循环内声明变量都是不好的做法,特别是如果您随后在循环外使用它们。
  • 即使没有来自神秘编译器的错误,这段代码也没有任何意义。您在循环中分配和重新分配变量,然后在循环外使用它们。所以它们要么是undefined(如果data.length0),要么是循环最后一遍的值。

标签: javascript jquery scope


【解决方案1】:

更新:您的问题的新版本完全改变了它,并使“编译器”的错误完全无稽之谈。我发现非常非常难以相信任何工具都会给您从您引用的(更新的)代码中引用的错误,并且恕我直言,我认为您提供的代码一定与您认为的不同你是。

您问题的success 处理程序的原始代码如下所示:

function (data) {
    for (var i = 0; i < data.length; i++) {
        var var1  = data[i][0];
        var var2  = data[i][1];
        var var3  = data[i][2];
        var var4  = data[i][3];
        $('.somediv').html('');
        $('.somediv').append('Somehtml');
    }
    some_function_declared_later(var1, var2, var3, var4);
 }

...下面的答案与该代码有关。在您的问题中使用最新版本的代码。

原答案

您在评论中说,有问题的“编译器”是“我的虚拟主机提供的一些在线工具”。

你说的很对,这些变量范围内。要么该工具不理解 JavaScript,要么它理解,但它正在做比语言更严格的“lint”事情。例如,jslint 会给你一个类似的错误(“不要在循环中声明变量”)。 (注意:jslint 给了你很多“错误”,这实际上只是它的作者对应该如何做的看法。)在 JavaScript 中,用 var 声明的变量在整个函数中声明,因为 JavaScript 不 (目前)具有块作用域,只有函数作用域和全局作用域。您的success 处理程序代码完全与此相同:

function (data) {
    var var1, var2, var3, var4;
    for (var i = 0; i < data.length; i++) {
        var1  = data[i][0];
        var2  = data[i][1];
        var3  = data[i][2];
        var4  = data[i][3];
        $('.somediv').html('');
        $('.somediv').append('Somehtml');
    }
    some_function_declared_later(var1, var2, var3, var4);
 }

我的博客上的更多信息:Poor misunderstood var

现在,即使没有来自神秘编译器的错误,这段代码看起来也很奇怪。您在循环中分配和重新分配变量,然后在循环外使用它们。所以它们要么是undefined(如果data.length0),要么是循环最后一遍的值。


重新编辑:

这可能和当前函数之外的 some_function_declared_later 的声明有关吗???

没有。如果问题是some_function_declared_later 没有在该行代码中定义,那么错误将抱怨some_function_declared_later,而不是变量。

函数声明,如var 语句,被提升到它们出现的范围的顶部。因此,如果您将其进一步降低:

function some_function_declared_later(a, b, c, d) {
    // ....
}

...你很好(除了奇怪的循环)。

如果你有 这个 再往下:

var some_function_declared_later = function(a, b, c, d) {
    // ....
};

...然后some_function_declared_later 将被声明为它上面的代码(因为var 被提升),但如果success 处理程序在代码分配行之前运行,它可能具有undefinedsome_function_declared_later var 的函数。 (这似乎不太可能,但我不会那样写,只是为了确定。)

【讨论】:

  • 谢谢!代码运行良好,但我担心警告!
  • @DipakYadav:好吧,您不应该在问题中使用最新版本的代码时收到警告,即使是像 jslint 这样的超限制性代码。
猜你喜欢
  • 2016-04-30
  • 1970-01-01
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 2020-12-24
  • 2016-01-09
  • 2018-09-19
相关资源
最近更新 更多