mal*_*ree 5 javascript function
有问题的代码很简单:
console.log("So it begins.");
foo();
function foo() { console.log("In foo()."); }
console.log("So it ends.");
Run Code Online (Sandbox Code Playgroud)
为什么foo()在定义之前执行(回顾性编辑:在Chrome和Safari中)?
我对此进行了修改,在Chrome,Safari和Firefox中测试了以下代码:
javascript:foo();function foo() { alert("Oh."); }
Run Code Online (Sandbox Code Playgroud)
Chrome和Safari中会显示提醒,而Firefox则保持静音.
这种令人惊讶的,不一致的行为有什么解释吗?
Javascript delarations总是会被移到顶部.它被称为吊装:
应该适用于所有浏览器的示例:http: //jsbin.com/abelus/edit
虽然其他人解释了函数的“提升”行为(我个人认为称之为上下文准备或预处理比提升更清楚),但 Firefox 不同行为的原因仍然没有答案。
首先,您应该知道函数声明和函数语句之间的区别之间的区别。
正如您的示例中所示,函数声明只能发生在两个位置:全局代码中(在任何函数之外)以及直接在另一个函数的函数体内,例如:
function foo () {}
function bar () {
function baz() {}
}
Run Code Online (Sandbox Code Playgroud)
以上所有函数都是有效的函数声明。
ECMAScript 规范不允许在其他地方定义函数声明,例如在块内:
if (true) {
function foo () {}
}
Run Code Online (Sandbox Code Playgroud)
上面的函数应该给你一个SyntaxError例外,但大多数实现都是仁慈的,它们仍然会预处理(提升)函数,即使实际函数不可访问(例如if (false) { function bar() {} })。
在 Firefox 中,允许使用函数语句,这意味着函数定义实际上在控件到达该特定语句时发生,例如:
if (true) {
function foo () { return true; }
} else {
function foo () { return false; }
}
Run Code Online (Sandbox Code Playgroud)
foo();在上述语句之后执行,在 Firefox 中会产生true,因为该if语句的第一个分支实际上被执行了。
在其他浏览器中,foo();会生成false,因为所有函数在进入执行上下文时都会进行预处理,并且最后一个函数将优先,即使从未到达语句false的分支。if
Firebug 控制台执行将其包装在块内的代码,这就是该函数在声明之前try-catch不可用的原因。
如果您在控制台上尝试:
console.log(typeof f); // "undefined"
function f () {}
Run Code Online (Sandbox Code Playgroud)
您将看到f尚未准备好,但如果将代码包装在函数内,您将看到预期的行为:
(function () {
console.log(typeof f); // "function"
function f () {}
})();
Run Code Online (Sandbox Code Playgroud)
同样,这是因为 nowf被定义为函数声明,因为它存在于匿名函数的主体中,并且不是语句块的一部分。