Javascript 函数声明或函数表达式

Javascript 函数声明或函数表达式,javascript,scope,function-declaration,function-expression,Javascript,Scope,Function Declaration,Function Expression,在块范围中定义函数时,我遇到了一个问题。考虑下面的程序: try { greet(); function greet() { alert("Merry Christmas!"); } } catch (error) { alert(error); } 我希望这个程序提醒圣诞快乐。但是在Firefox中,is给了我以下参考错误: ReferenceError: greet is not defined 在Opera和Chrome上,它会像我预期

在块范围中定义函数时,我遇到了一个问题。考虑下面的程序:

try {
    greet();

    function greet() {
        alert("Merry Christmas!");
    }
} catch (error) {
    alert(error);
}
我希望这个程序提醒
圣诞快乐。但是在Firefox中,is给了我以下
参考错误

ReferenceError: greet is not defined
在Opera和Chrome上,它会像我预期的那样提醒问候语

显然,Firefox将块范围内的函数视为
FunctionExpression
,而Opera和Chrome将其视为
FunctionDeclaration

我的问题是为什么Firefox的行为会有所不同?哪个实现更符合逻辑?哪一个符合标准

我知道JavaScript中的声明是被提升的,因此如果在同一范围内的两个或多个不同块中声明相同的函数,那么就会出现名称冲突


但是,如果每次声明函数时都重新声明它,这样您就可以执行如下操作,这不是更符合逻辑吗

greet(); // Merry Christmas!

function greet() {
    alert("Merry Christmas!");
}

greet(); // Happy New Year!

function greet() {
    alert("Happy New Year!");
}

我认为这将非常有用,除了解决我上面描述的块作用域问题。

实际上,块作用域内的函数声明没有明确标准化,行为依赖于实现。不同的实现会做出不同的响应。如果试图在if语句中声明函数,也会遇到同样的奇怪情况


ES5规范建议实现者在块内进行函数声明,并将其标记为警告或错误。

因此不应在块范围内声明函数。也许这是一个很好的编程实践。javascript旁边是异步语言。所以在调用之前,您需要定义您的函数it@Janim007,这个问题的关键是,在JavaScript中,您可以在定义函数之前对其进行拓扑调用。@Janim007-JavaScript不是异步语言。事实上,没有任何JavaScript构造可以为语言添加异步性。事件循环和
setTimeout
不是该语言的功能。它们是DOM的特性,并且是网页交互编程所必需的:JavaScript相当。。。松散地。。。而“提升”行为实际上并不存在于语言规范中。在块范围中定义的函数很简单,是未定义的行为。它们需要位于全局范围或函数的顶层,否则您将在未定义的实现中执行它想要执行的任何操作。它可以工作。它可能会给出一个“未定义”的异常。它可以格式化你的硬盘,为你妈妈订阅每月红薯俱乐部,或者给你的猫扎染。没有定义。至少这不是C级别的未定义行为。“每次声明函数时都重新声明它,以便您可以执行类似的操作”-它们被重新引用,只有声明发生一次并被提升。在上一段中,你没有确认你理解提升吗?是的,我理解JavaScript中的提升。不,我的句子非常清楚。我想说的是,每次解释器遇到
函数声明时(每次声明时),它应该只将其提升到同一范围内函数的上一次声明(重新声明函数)。由于JavaScript中不存在此功能,因此不能引用当前的JavaScript标准使其无效。这只是一个建议。建议在JavaScript中实现同一函数的多个声明。希望这能给你带来一些清晰。圣诞快乐@katspaugh哦,我明白了。感谢上帝,ES董事会的任何人都没有想到这一点。圣诞快乐,阿迪!:)