前言
在茫茫前端路各种专业化、对象化、工程化的今天,你以为光会切个图写点DIV\CSS就能称前端了?
在Node.js火爆当道,在AngularJS\Express\Vue\React等各种框架层出不穷之时,万变不离其宗,唯一能让自己心安的,或许还是老老实实一点点打下扎实高端大气上档次的JavaScript基础,玩转玩遍它才是王道呀。自从学习JavaScript以来,它的无拘无束的「自由」实在令人印象深刻且赞,但同时也带来太多的奇葩与有些别扭的语法糖。
其实,换个角度出发,这些有时候让人不那么愉快的一面,不也正是JavaScript独特的美和气质么?OK,接下来我就一点点把平常遇到的一些“美”给记录下来,以供小伙伴们一同欣赏:)
发现美
前两天在V2EX看到一个童鞋的疑问:
JavaScript 里 var x = i = 0 这个写法是什么意思呢?
这还有啥意思!不就是最最最简单的赋值语句嘛!C\C++\Java等各种语言都有的嘛!
|
|
打完收工!奏是这么简单,哟嘿哟嘿~
等等,既然你这么问,想必来者不善,不妨又是给我埋的一个坑吧~~那我们来动手看看是否有坑!
|
|
这样的结果,怎能不感慨“好一个人参惨淡”,在了解这个背后的原因之前,我们先来了解下JavaScript官方对于变量Var的一些定义及解释:
- 变量的声明
1.使用var多次声明同一个变量,是合法的; 重复的声明并初始化变量值,只是相当于普通的赋值语句;
2.读取一个未声明的变量值,JavaScript会产生一个错误;
3.尝试给一个未经var声明的变量赋值,JavaScript会隐式声明该变量,隐式声明的变量被直接创建为全局变量;
4.无论是全局变量还是局部变量,最好都建议使用var进行声明(strict严格模式下不声明var变量直接报错);
看完这样的定义,一下子秒懂,有木有?!
刚才我们上面童鞋那样的写法,直接会导致 i 变成全局变量, 所以等同写法:
|
|
所以,看看,这是一个多么糟糕的写法,直接会隐式创建一个全局变量,继而引发变量污染。所以,我们切记,在日常开发过程中,不要这么写!
延伸一
那到这里,突然还有个疑问,你们说,这显式创建的全局变量和隐式创建的全局变量,自然都是window的属性,那他们俩者真的完全一样么?我们通过ECMAScrpit提供的属性特性查询方法,来发现他们之间的秘密。
|
|
通过上面的查询发现,原来还是有差别的,我们再用delete删除属性来验证下,配置性configurable为false的属性无法删除,即通过变量var显式声明全局对象的属性无法删除。
结论就是:在全局作用域下,使用var定义的变量不可以delete,没有var定义的变量可以delete。也就说明隐式全局变量严格来说不是真正的变量,而是全局对象的属性,因为属性可以通过delete删除,而变量不可以。
延伸二
我们试着来再看这一段小程序,看看结果如何?
|
|
为何会是这样的结果?这个跟使用var定义变量还会提升变量声明有关。
在函数内部显式声明了一个与全局变量同名的局部变量,第一次alert, 解析器就会先将变量声明提升,所以就导致局部变量wss是已经被声明了,但是没有初始化值,所以提示undefined; 而第二次的alert,wss = “local” 之后的,也就是局部变量wss完成了初始化,所以提示为local。
该段代码实际相当于:
|
|
那如果不使用var定义变量呢?
|
|
结论就是:使用var定义的变量的声明提前,未使用var定义的变量声明不变。
结尾
JavaScript一个如此简单的赋值语句背后,竟隐藏着太多奇葩的特性,而这些一个不留神,就将让你的程序陷入一个变量污染噩梦里。美,也是有杀伤力滴~