以下代码段在Firefox和Chrome中显示不同输出的任何原因:
var sayHo;
console.log(typeof(sayHey));
console.log(typeof(sayHo));
if(true) {
function sayHey() {
console.log("Hey, inside if");
};
sayHo = function() {
console.log("Ho, inside if");
};
}
else {
function sayHey() {
console.log("Hey, inside else");
};
sayHo = function() {
console.log("Ho, inside else");
};
}
sayHey();
sayHo();
Chrome(v31)输出
Firefox(第26栏)输出
我预计Chrome会提供相同的输出。在解析时,内部的函数声明将覆盖if中的函数声明。因为JavaScript会尝试提升函数声明,因此覆盖。
答案 0 :(得分:2)
Firefox和Chrome使用不同的JavaScript引擎(分别是SpiderMonkey和V8)。 Chrome行为可以被视为“错误”或“易用性功能”。在V8中,if语句中的函数定义(而不是将匿名函数赋值给变量)在执行前执行。这是一个设计决定。
答案 1 :(得分:0)
这一切归结为hoisting差异:
函数声明和变量声明始终由JavaScript解释器隐藏在其包含范围的顶部(“悬挂”)。显然,功能参数和语言定义的名称已经存在。这意味着代码如下:
function foo() {
bar();
var x = 1;
}
实际上是这样解释的:
function foo() {
var x;
bar();
x = 1;
}
考虑这个例子:
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
此代码相当于:
function test() {
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
}
test();
看看函数声明发生了什么:它被悬挂。
Leet看看更简单的样本:http://jsbin.com/UKICENE/4/edit
console.log(typeof(sayHey));
if(true) {
function sayHey() {
console.log("Hey, inside if");
};}
sayHey();
这将在chrome中产生function
。
但它会在FF中产生undefined
。
Hoeever - 通过setTimeout推迟计算将产生与chrome相同的结果:
console.log(typeof(sayHey));//undefined
setTimeout(function (){console.log(typeof(sayHey));},1000); //function
if(true) {
function sayHey() {
console.log("Hey, inside if");
};}
sayHey();
所以,就像Šime所说,它推迟了评估。
如果你问我,我认为chrome正在做正确的事