Javascript if语句中JS函数的奇怪行为,为什么?
为什么下面的代码会返回“显而易见”、“惊讶!”(最后是“为什么?”)。它应该返回“预期”,不是吗?Javascript if语句中JS函数的奇怪行为,为什么?,javascript,jquery,Javascript,Jquery,为什么下面的代码会返回“显而易见”、“惊讶!”(最后是“为什么?”)。它应该返回“预期”,不是吗? 在第一个if中,我们使用匿名函数,在第二个中,我们使用“命名”函数 var a = 5; if (a == 5) { var b = function () { return "obvious"; }; } else { var b = function () { return "never"; }; } if (a == 5) {
在第一个
if
中,我们使用匿名函数,在第二个中,我们使用“命名”函数
var a = 5;
if (a == 5) {
var b = function () {
return "obvious";
};
} else {
var b = function () {
return "never";
};
}
if (a == 5) {
function c() {
return "expected";
}
} else {
function c() {
return "surprise!";
}
function d() {
return "how come?";
}
}
alert(b());
alert(c());
alert(d());
这意味着,函数a(){}不等于var a=function(){}
那么,第二个问题,为什么JS需要这种特殊的行为?这有什么好处 不,它不应该这样做,因为函数定义语句的语义与您显然认为的不同 函数定义语句总是被提升到封闭函数(或作用域)的顶部。当有多个同名函数定义语句时,最后一个语句获胜。这不是一个动态的执行时间问题。将函数定义语句放在条件代码块中确实应该在语法上被禁止,但事实并非如此。不要这样做
当然,您可以使用函数实例化表达式来创建分配给变量的函数对象。这将如您所期望的那样工作。@Pointy是正确的。函数c()和d()在计算第一个if语句之前声明。这就是为什么当您调用警报时,它们会执行它们所执行的操作。所有变量声明和函数声明都会被提升到作用域的顶部,在本例中是脚本的顶部。这意味着代码被解释为
var a,b;
function c() {
return "expected";
}
function c() {
return "surprise!";
}
function d() {
return "how come?";
}
a = 5;
if (a == 5) {
b = function () {
return "obvious";
};
} else {
b = function () {
return "never";
};
}
if (a == 5) {
}
else {
}
alert(b());
alert(c());
alert(d());
请注意,最后一个if语句是空的,因为它们包含的所有函数声明都已挂起。函数c
的第二个声明掩盖了第一个声明
我建议您避免在block语句中使用funciton声明语法。从技术上讲,它不是合法的JavaScript,但每个浏览器都支持它,尽管这会导致混乱,正如您所指出的
函数a(){}不等于var a=function(){}
对。情况从来就不是这样
那么,第二个问题,为什么JS需要这种特殊的行为?这有什么好处
JavaScript提升函数声明,以允许脚本中稍后声明的函数被脚本中较早的函数使用。这使得代码组织更加灵活。我想您指的是函数声明。但是Mozilla[1]有一个扩展,它将块内看似函数的delcaration视为函数语句,因此它不是“提升”的,而是有条件地求值的,提供了条件声明的外观。其他浏览器将它们视为声明,并按照您所说的进行操作。1.不幸的是,我无法在Mozilla或Firefox中进行测试,以确定情况是否仍然如此。我待会再查。也许是“声明”;区别在于(正如您清楚知道的)有一个函数实例化的工具,它是表达式语法的一部分,还有一个定义和声明命名函数的语句。它们有一些共同的效果,但语句与实例化子表达式明显不同。