4

我试图理解为什么 JSLint 在以下示例中抱怨隐含的全局变量:

var TEST = (function () {
  var count = 0;

  function get_count() { 
    return add_one(); 
  }

  function add_one() {
    count += 1;
    return count;
  }

  return { 
    get_count: get_count
  };
}());

通过 JSLint 运行它会给出错误:

第 5 行字符 12 处的问题:未定义“add_one”。

还说:

隐含全局:add_one 5

如果在add_one()函数之前移动get_count()函数,错误就会消失。但是,使用上面的代码,当您在浏览器中运行它时不会产生任何错误。谁能解释为什么 JSLint 抱怨?

谢谢!
马特

4

3 回答 3

11

这是因为JSLint使用了Pratt Parser一个自上而下的解析器,而不是一个成熟的 JavaScript 解释器。如果它被真正解释,那么它不会给你那个错误。

add_one是一个隐含的全局变量,因为解析器还没有遇到该变量,因此它假定您的周围代码将具有该变量。但是,如果你把它翻过来,那么解析器已经遇到了这个add_one变量,而且都是桃子和奶油:-)

顺便说一句,我注意到您的关闭函数行中有一个小错字: }());应该是})();.

于 2010-10-21T03:15:53.007 回答
1

我更改了声明方法的顺序,它将解决您的问题。正如另一个答案中提到的,一些 JavaScript 解析使用自上而下的方法来读取代码,类似于 C 编程语言的方式。现代解释器和编译器使用 2 pass 方法。第一步是将方法读取/编译到内存中。如果它遇到任何它不知道的方法调用,它将查看内存中的整个方法集以确定它是否存在。我建议修复订单,因为虽然它可能不会导致问题,但它会随着更改更快地将方法加载到内存中。

var TEST = (function () {
  var count = 0;

  function add_one() {
    count += 1;
    return count;
  }

  function get_count() { 
    return add_one(); 
  }

  return { 
    get_count: get_count
  };
}());
于 2010-10-31T13:49:33.527 回答
1

你得到 *add_one not defined* 因为 JSLint 认为函数表达式应该以正确的顺序声明,而对于另一个问题(“*隐含全局:add_one 5*”),你放一个注释就足够了,例如 /*globals add_one * / 在脚本的顶部

于 2010-12-15T00:46:25.070 回答