JS:变量声明后的分号

时间:2014-10-05 11:49:53

标签: javascript

我偶然发现了一个非常有趣的问题,很难找到。 自发现以来,并不难解决,但我想找到解释,以便将来不再重复类似的事情。 这是我的JS代码的简化版本:

//the following does not work:
var A = function(){
    console.log('I am A')
}
(function B(){
    console.log('I am B');  
})()
A();

我期待着看到我是B'然后'我是A'在控制台。但是,有 未捕获的TypeError:undefined不是函数

经过长时间的调试后我发现, A 函数之后缺少的分号会导致问题:

//the following works as expected:
var A = function(){
    console.log('I am A')
};
(function B(){
    console.log('I am B');  
})()
A();

此外,当你以其他方式宣布这个功能时,一切都会好起来的:

//this works too
function A(){
    console.log('I am A')
}
(function B(){
    console.log('I am B');  
})()
A();

因此,它是一个破坏代码的变量声明和括号的组合。

你能解释一下为什么会这样吗?

这是测试的小提琴: http://jsfiddle.net/wxu2f8en/

2 个答案:

答案 0 :(得分:5)

这是因为没有分号,表达式可以继续到下一行。它可以帮助您了解是否删除了换行符:

var A = function(){
    console.log('I am A')
}(function B(){
    console.log('I am B');  
})()

在这里,您创建一个匿名函数表达式,然后使用单个参数(即function B)调用它。然后你调用它的结果。但是,您的第一个函数不返回任何内容,因此返回undefined。然后,你不能调用undefined(undefined不是函数)。

但是,功能块的工作方式不同。这不能在飞行中调用。因此,您的第二个示例工作正常。

您可以在MDN上阅读更多内容:

答案 1 :(得分:1)

您需要了解function expression and function declaration之间的区别。 可以立即调用函数表达式,这就是为什么调用第一个匿名函数将函数B作为参数传递的原因。此外,你的第一个函数没有return语句,所以它确实返回undefined(显然不是函数)。

JS具有automatic semicolon insertion功能,您不应该依赖它。使用JSHint之类的工具来帮助您编写不易出错的代码。