Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript if语句中JS函数的奇怪行为,为什么?_Javascript_Jquery - Fatal编程技术网

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中进行测试,以确定情况是否仍然如此。我待会再查。也许是“声明”;区别在于(正如您清楚知道的)有一个函数实例化的工具,它是表达式语法的一部分,还有一个定义和声明命名函数的语句。它们有一些共同的效果,但语句与实例化子表达式明显不同。