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() {},它是一个声明,而当你写成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 的函数体中,就好像你在做undefined(),这会引发错误。