Chr*_*thy 101 javascript function jslint jshint
当我的JavaScript调用一个在页面下面定义的函数而不是调用它时,JSHint会抱怨.但是,我的页面用于游戏,并且在整个内容下载之前不会调用任何函数.那么为什么订单功能出现在我的代码中呢?
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
我在里面呻吟.看起来我需要花一天时间重新订购六千行代码.使用javascript的学习曲线根本不是很陡峭,但它非常loooooong.
Zir*_*rak 279
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() {}
Run Code Online (Sandbox Code Playgroud)
bar();
function bar() {
foo(); //This will throw an error
}
var foo = function() {}
Run Code Online (Sandbox Code Playgroud)
bar();
function bar() {
foo(); //This _won't_ throw an error
}
function foo() {}
Run Code Online (Sandbox Code Playgroud)
function bar() {
foo(); //no error
}
var foo = function() {}
bar();
Run Code Online (Sandbox Code Playgroud)
这是因为所谓的吊装!
定义函数有两种方法:函数声明和函数表达式.差别很烦人,所以我只是说这个稍微错误的东西:如果你正在写它function name() {},它就是一个声明,当你把它写成var name = function() {}(或者一个匿名函数分配给一个返回的东西,就像那样),它就是一个函数表达式.
var foo = 42;
//the interpreter turns it into this:
var foo;
foo = 42;
Run Code Online (Sandbox Code Playgroud)
var foo = 42;
function bar() {}
//turns into
var foo; //Insanity! It's now at the top
function bar() {}
foo = 42;
Run Code Online (Sandbox Code Playgroud)
该var声明"抛出"的创作中foo,以最顶端,但并不值分配给它.函数声明接下来排成一行,最后分配一个值foo.
bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;
Run Code Online (Sandbox Code Playgroud)
只有声明中foo移动到顶部.只有在bar完成所有提升之前的调用之后才会进行分配.
bar();
function bar() {}
//turns to
function bar() {}
bar();
Run Code Online (Sandbox Code Playgroud)
var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();
Run Code Online (Sandbox Code Playgroud)
就像普通的变量,首先foo是宣布在该范围内的最高点,然后将它分配一个值.
bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
Run Code Online (Sandbox Code Playgroud)
正如我们之前看到的那样,只有创建foo被提升,分配才出现在"原始"(未提升)代码中.当bar被调用时,它被foo赋予一个值,所以foo === undefined.现在在函数体中bar,就像你正在做的那样undefined(),它会抛出一个错误.
主要原因可能是JSLint只对文件进行了一次传递,因此它不知道您将定义这样的函数.
如果使用函数语句语法
function foo(){ ... }
Run Code Online (Sandbox Code Playgroud)
实际上,在声明函数的地方没有任何区别(它总是表现为声明在开头).
另一方面,如果您的函数设置为常规变量
var foo = function() { ... };
Run Code Online (Sandbox Code Playgroud)
您必须保证在初始化之前不会调用它(这实际上可能是错误的来源).
由于重新排序大量代码很复杂并且本身可能是错误的来源,我建议您搜索一个解决方法.我很确定你可以事先告诉JSLint全局变量的名称,所以它不会抱怨未声明的东西.
对文件的开头发表评论
/*globals foo1 foo2 foo3*/
Run Code Online (Sandbox Code Playgroud)
或者您可以在那里使用文本框.(我也认为你可以在内部jslint函数的参数中传递它,如果你可以插入它.)
有太多人对 JavaScript 的编写方式提出武断的规则。大多数规则都是垃圾。
函数提升是 JavaScript 中的一项功能,因为它是一个好主意。
当您有一个内部函数(通常是内部函数的实用程序)时,将其添加到外部函数的开头是一种可接受的代码编写风格,但它确实有一个缺点,即您必须通读详细信息才能了解内容外部函数可以。
您应该在整个代码库中坚持一个原则,要么将私有函数放在模块或函数的前面或最后。JSHint 对于强制一致性很有用,但您绝对应该调整 .jshintrc 以满足您的需求,而不是根据其他人古怪的编码概念调整您的源代码。
您可能在野外看到的一种编码风格应该避免,因为它没有任何优势,只会带来重构的痛苦:
function bigProcess() {
var step1,step2;
step1();
step2();
step1 = function() {...};
step2 = function() {...};
}
Run Code Online (Sandbox Code Playgroud)
这正是函数提升要避免的。只需学习该语言并利用其优势即可。