JSHint会抱怨。但是,我的页面用于游戏,并且在整个内容下载之前不会调用任何函数。那么为什么订单函数出现在我的代码中呢?
<编辑:编辑:我想我可能已经找到了答案。http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
我在里面呻吟。看起来我需要花费另一天来重新订购六千行代码。使用javascript的学习曲线根本不陡峭,但它非常loooooong。
答案 0 :(得分:272)
tl; dr 如果你没有在任何事情加载之前调用任何东西,你应该没问题。
编辑:有关概述,其中也涵盖了一些ES6声明(let
,const
):https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet
这种奇怪的行为取决于
以下是一些例子。
bar(); //This won't throw an error
function bar() {}
foo(); //This will throw an error
var foo = function() {}
bar();
function bar() {
foo(); //This will throw an error
}
var foo = function() {}
bar();
function bar() {
foo(); //This _won't_ throw an error
}
function foo() {}
function bar() {
foo(); //no error
}
var foo = function() {}
bar();
这是因为提升!
定义函数有两种方法:函数声明和函数表达式。差别很烦人,所以我只想说这个有点错误的事情:如果你写的是function name() {}
,那就是声明,当你把它写成{{1}时(或分配给返回的匿名函数,类似的东西),它是一个函数表达式。
var name = function() {}
var foo = 42;
//the interpreter turns it into this:
var foo;
foo = 42;
var foo = 42;
function bar() {}
//turns into
var foo; //Insanity! It's now at the top
function bar() {}
foo = 42;
语句将var
的创建抛出到最顶层,但尚未为其分配值。函数声明接下来排成一行,最后将一个值赋给foo
。
foo
仅将bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;
的声明移至顶部。只有在调用foo
之后才会进行分配,此时所有吊装都会发生。
bar
bar();
function bar() {}
//turns to
function bar() {}
bar();
就像常规变量一样,首先var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();
在范围的最高点宣布,然后为其分配一个值。
foo
正如我们之前看到的那样,只有bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
的创建被提升,分配才出现在“原始”(未提升)代码中。调用foo
时,会在为bar
分配值之前,foo
。现在在foo === undefined
的函数体中,就好像你正在做bar
,这会引发错误。
答案 1 :(得分:6)
主要原因可能是JSLint只对文件进行了一次传递,因此它不知道你将定义这样的函数。
如果使用函数语句语法
function foo(){ ... }
在声明函数的地方实际上没有任何区别(它总是表现为声明在开头)。
另一方面,如果您的功能设置为常规变量
var foo = function() { ... };
您必须保证在初始化之前不会调用它(这实际上可能是错误的来源)。
由于重新排序大量代码很复杂并且本身可能是错误的来源,我建议您搜索一个解决方法。我很确定你事先可以告诉JSLint全局变量的名称,所以它不会抱怨未申报的东西。
对文件的开头发表评论
/*globals foo1 foo2 foo3*/
或者您可以在那里使用文本框。 (我也认为你可以在内部jslint函数的参数中传递它,如果你可以插入它。)
答案 2 :(得分:3)
有太多人推行关于如何编写JavaScript的任意规则。大多数规则都是完全垃圾。
函数提升是JavaScript中的一项功能,因为它是一个好主意。
如果你有一个内部函数,它通常是内部函数的实用程序,将它添加到外部函数的开头是一种可接受的编写代码的方式,但它确实有一个缺点,你必须通读细节到得到外部函数的作用。
您应该在整个代码库中坚持一个原则,即将私有函数放在模块或函数的第一位或最后一位。 JSHint有助于强制执行一致性,但您应该绝对调整.jshintrc以满足您的需求,而不是将源代码调整为其他人的古怪编码概念。
你应该避免在野外看到的一种编码风格,因为它没有给你任何优势,只有可能的重构痛苦:
function bigProcess() {
var step1,step2;
step1();
step2();
step1 = function() {...};
step2 = function() {...};
}
这正是提升功能所要避免的。只需学习语言并发挥其优势。
答案 3 :(得分:1)
只提升函数声明而不是函数表达式(赋值)。