JavaScript中的语句结束符';'

来源:互联网 发布:网络小贷与p2p的区别 编辑:程序博客网 时间:2024/06/07 22:43

语句结束的分号还是挺重要的

let a,b,ca = [1, 2, 3, 4]a.forEach((n) => {    n *= n;})[b, c] = a

以上代码,乍看之下似乎没什么问题,除了最上面两行的声明与赋值之外,就是将数组a的每一项元素平方操作,然后通过数组解构赋值的方法给变量b和c分别赋值为数组a的前两个元素。、

但是运行起来就会发现
运行报错

神马?!居然报错了?!

不要慌,来分析下报错信息:Cannot set property 'undefined' of undefined 无法在undefined上设置属性’undefined’。这种错误熟悉不熟悉?

很明显,这种错误一般发生在给对象添加属性,而要添加属性的对象却是一个undefined值的时候。

那么问题来了:我们什么时候进行了给对象添加属性的操作了呢?

先回想一下,给对象添加属性的方法,最常用的就是点语法了object.someProperty ,另一种则是关联数组语法object["someProperty"] ,当然,还有其他方法,比如Object.defineProperty()

不过这里并不是要讨论这些,在看到关联数组语法的时候,有没有眼前一亮?没错,问题就出在这里。

let a,b,ca = [1, 2, 3, 4]a.forEach((n) => {    n *= n;});[b, c] = a

加上分号就没错了

那么原因呢?

JavaScript中之所以可以不加语句结束符,是因为你不加,系统会自动帮你加上。但是系统并不能知道你的一条完整语句具体到哪里结束,因此系统只能根据语句是否完整、能否继续等条件来判断。

很显然,a.forEach()这条遍历语句是完整的;但是在后面的数组解构依然可以跟它连起来成为一条对象属性的赋值语句,因此系统并没有在遍历语句结束时自动地加上语句结束符。

进行步骤的拆解的话,可以这么看,记得任何语句都是有返回值的,所以不妨将a.forEach(...) 赋值一个临时变量,这样就可以更加清晰起来了

temp = a.forEach();temp[b, c] = a

你可能会说,这种情况很少发生的啦。没错,确实很少发生,我也是在前几天做项目的时候才初次遇到这种因为一个分号引起的错误。因为项目中使用了eslint,要求在可以使用解构赋值的情况下,必须使用解构赋值,不然就会报错。然后最初是没有这项强制要求的,而且有些人并不会特意去修改这些不影响实际代码运行的问题。而我在修改了之后才发现了这样的问题。但是我想说的是,除了这种数组解构赋值的情况,真的就没有其他情况了吗?并不是这样的吧。

而且作为一个开发者,养成一个写规范代码的习惯还是很有好处的,至少我是这样认为的。