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
移动到顶部。分配仅在调用 to 之后出现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()
,这会引发错误。