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(),这会引发错误。