过节了!今天写代码我就不加分号!会怎样嘛?

518 阅读4分钟

前言

今天是程序员日,又正好赶上周末。过节嘛,就要轻松一下,在代码上怎样体现呢。

考虑到有些小伙伴会纠结于写js代码要不要加分号的问题,今天就帮大家总结一下什么情况下可加可不加,什么情况下必须加

先说一下,并没有做到大而全,过节嘛!研究那么多平常开发也用不到的边边角角干嘛呀,还是轻松掌握一些经常碰到的情况好了。

分号的作用

分号其实是一条空语句,没有需要执行的代码,但也不会报错

明确不使用分号的情况

首先,以下三种情况,语法规定本来就不用在结尾添加分号。

  • 循环语句
for ( ; ; ) {

} // 不用加分号

while ( ) {

} // 不用加分号

do {

} while (); // 除外,主要因为是以小括号结尾的
  • 分支语句
if ( ) {

} // 不用加分号

switch ( ) {

} // 不用加分号
try {

} catch ( ) {

} // 不用加分号
  • 函数声明
function fn( ) {

} // 不用加分号

var fn = function () {

} // 函数表达式除外

如果上面几种情况下,加了分号,也不会报错,因为会被解析成空语句。

自动断句

在js中,除了分号会被当做一条语句的结束,换行也会被当做语句的结束。

大多数情况的换行都会被当做语句的结束。但是为了最大程度不让程序报错,js还有一个机制:如果上下两行可以被视为同一条语句,则就会被当成同一条语句。

遇到这种情况,如果不加分号进行断句,而想依靠换行来断句,可是换行在一些情况下又做不到断句,就会出错了。

无视换行,可又不报错的情况

var // 无视换行
a // 无视换行
= // 无视换行
1
console.log(a); // 1
console.log('abc' // 无视换行
.length) // 3
var obj = {foo: 'bar'}
console.log(obj // 无视换行
.foo) // bar
function fn(param1, param2) {
  console.log(param1, param2);
}
fn(1, // 无视换行
2) // 1 2
var a 
if (true) // 无视换行
a = 1 // 特别注意这里的换行被视为了断句,如果不看做断句,是会报错的,
// 因为if语句后面代码块只有在一条语句的情况下才能省略大括号,如果无视换行,就是两条语句了。
console.log(a)

无视换行,上下看成一行,程序会出问题的情况

var a = 1
var b = 2
var c = a + b
(11 + 22) // Uncaught TypeError: b is not a function

// 由于无视换行,等同于下面的代码,b被当成了函数,自然就会报错了
var c = a + b(11 + 22)
var a = 1
var c = [1, 2]
[a]
console.log(c); // 2 虽然没有报错,但是结果不对,c明明是数组

// 同样是视为如下同一行代码的原因
var c = [1, 2][a] // 这样是在获取数组[1, 2]的第1个元素,结果自然为2
var a = 1
var b = 2
var c = 3

a
++
b
--
c
console.log(a, b, c); // 1 3 2

我们希望上面解析为:

var a = 1
var b = 2
var c = 3

a++
b--
c
console.log(a, b, c); // 2 1 3

实际解析为:

var a = 1
var b = 2
var c = 3

a
++b
--c
console.log(a, b, c); // 1 3 2

原因:自增和自减运算符在行首的时候,会在他们前面自动添加分号

正视换行但是程序会出现错误的情况

function fn() {
  return // 因为换行而断句,返回undefined
  {
    name: 'xiaoming'
  }
}
console.log(fn()) // undefined

看一个很有意思的关于分号加不加的for循环

for(var i = 0; i < 6; i++){
  console.log(i); // 0 1 2 3 4 5
}
for(var i = 0; i < 6; i++);{
  console.log(i); // 6
}

以上代码等同于

for(var i = 0; i < 6; i++);
{
  console.log(i); // 6
}

还可以进一步简化

for(var i = 0; i < 6; i++);
console.log(i); // 6

看出来原因了吗,其实for循环的循环体只是一条空语句 分号;,其实循环体如果是一条语句的话,可以不带{}{}只是用来包裹多条语句的代码块。如果是一条语句自然就可以省略。所以后面的打印,只打印一次,且是i循环之后的值

也就意味着不带分号的for循环也是可以省略{}

for(var i = 0; i < 6; i++)
console.log(i); // 0 1 2 3 4 5

神不神奇?惊不惊喜?意不意外?

总结

这里只谈经常会碰到的情况,至于别的一些几乎在开发中碰不到的情况就不做考虑了!

  • () [] ++ --位于行首的时候,上一行一定要加分号
  • 在使用return的时候,如果希望返回后面的数据,就不要换行。

另外:因为一些压缩代码的库不会自动帮你加分号,如果你不加分号的话,就不能使用这些库进行代码的压缩了。