tl;博士如果你在加载所有内容之前不调用任何内容,你应该没问题。
编辑:对于概述,其中还涵盖了一些ES6声明(,):https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheetlet
const
这种奇怪的行为取决于
- 如何定义函数和
- 当您打电话给他们时。
下面是一些示例。
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;
只有 的声明被移到顶部。只有在调用 to 之后,即在所有吊装发生之前,才进行分配。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()