很多次我看到在函数声明之后或在module模式脚本的匿名“返回”函数之后使用分号。什么时候在花括号后使用分号合适?
什么时候应该在花括号后使用分号?
在语句后使用分号。这是一个声明:
var foo = function() {
alert("bar");
};
因为它是一个变量赋值(即创建一个匿名函数并将其赋值给一个变量)。
两个不是语句的东西是函数声明:
function foo() {
alert("bar");
}
和块:
{
alert("foo");
}
注意:没有分号的相同块结构也适用于for
,do
和while
循环。
不要使用分号:
...如果这只是您的日常函数声明:
function foo() {
} // No semicolon
使用分号:
...如果这是一项任务:
var foo = function() {
}; // Semicolon
...或自调用函数:
(function () {
})(); // Semicolon
你永远不需要;你总是可以(除了之前else
和while
)。
解释:
不幸的是,JavaScript 分号是可选的。
因此,您永远不需要添加分号。
用分号终止每个语句是(非常)好的做法。
唯一以 a}
结尾的语句是以对象字面量(例如 JSON)或函数表达式结尾的语句。
因此,最佳做法是在以下两个大括号后放置分号(仅):
var myFunc = function() { };
var myobject = { };
如果我们有一个自调用函数,我们需要在它前面放一个分号,否则它就成为前面赋值语句的一部分。考虑以下:
testClass = function(name) {
document.write ("Instantiating testClass<br />");
this.name = name;
}
testClass.prototype.report = function() {
document.write ("I'm " + this.name + "<br />");
return 1;
}
testClass.prototype.testMethod = function(param) {
document.write ("Running testMethod with parameter value " + param + "<br />");
return 2;
} // notice that there is no semicolon here
(function() {
document.write ("Running self-invoking function<br />");
return 3;
}());
if (typeof(testClass.prototype.testMethod) !== "function") {
document.write ("testMethod type: " + typeof(testClass.prototype.testMethod));
document.write (", value: " + testClass.prototype.testMethod + "<br />");
}
var testOb = new testClass("Bill");
testOb.report();
testOb.testMethod(4);
这将产生以下输出:
“运行自调用函数
运行 testMethod 参数值为 3
testMethod 类型:数字,值:2
实例化 testClass
我是比尔”
...加上浏览器报告的 JavaScript 错误:testOb.testMethod is not a function
这当然不是我们想要的。为什么testMethod
在我们实例化类之前立即运行?为什么当我们想将它作为成员方法调用时它不再存在?
发生的事情是testMethod
分配的不是我们的函数定义,而是函数定义的返回值。并且函数定义本身是匿名运行的。这是如何:
- 的
testClass
构造和部件的方法report
被成功地定义/分配。 - 因为 for 的定义后面没有分号
testMethod
,()
后面的自调用函数就变成了一个调用操作符,导致我们认为我们定义的testMethod
变成了一个立即调用的匿名函数,而这个函数的返回值下面的匿名函数成为它的参数列表。这解释了打印输出的顺序 - 我们的自调用函数首先运行,因为它被评估为参数。 - 由于我们预期的函数定义返回 2,因此分配给 的是这个 2
testMethod
,而不是函数定义。我们打印的类型和值证实了这一点testMethod
。 - 现在
testClass
已成功实例化,testOb
并且其report
方法按预期工作,证明类定义在其他方面是完整的。 - 当我们尝试调用 时
testMethod
,解释器告诉我们它不是一个函数——这是正确的,因为它是一个值为 2 的数字。
如果我们在 的定义后面加一个分号testMethod
,它将把它的赋值与自调用函数的调用分开,我们就会得到我们期望的结果:
“运行自调用函数
实例化 testClass
我是 Bill
Running testMethod 参数值为 4”
或者我们甚至可以将它直接放在匿名函数之前:
;(function() {...
但我建议,既然问题是由于赋值语句末尾没有分号,我们或许应该养成这样定义函数后总是放分号的习惯。即我上面的所有函数在右大括号后都应该有一个分号,因为它们都是匿名函数的赋值。