上QQ阅读APP看书,第一时间看更新
2-3 变量提升
ECMAScript中有一个十分奇怪的语法规则:变量提升。如果你使用了一个从未声明过的变量,程序运行会直接抛出异常。但是如果代码中有过对此变量的声明,无论在声明前使用还是在声明后使用,程序都不会抛出异常,例如:
还有一点,如果你直接对一个未经声明的变量进行赋值,就相当于直接在全局作用域中创建了这样一个变量,这是一种十分危险的做法,会造成无意的变量泄露,例如:
造成这种语法特性的原因是:JavaScript解释器在对代码进行扫描时,会将全局作用域中声明的变量和函数先定义为全局符号,运行到具体声明处才进行赋值。这种语法特性多多少少会对开发者造成一些误解,在许多流行的编程语言中,变量在声明之前是不能使用的。如果说上面的示例代码你仍然觉得没有什么好紧张的,那么下面的代码就能说明问题了:
上面的示例代码中,首先if条件判断语句值为假,if代码块永远不会执行到,但是从打印结果可以看出,第一句打印并未抛出异常,name变量还是被声明了。而后面的循环结构中,我们在for循环条件结构中声明了一个i变量,在循环体内声明了sum变量,可是当循环结束后,i变量依然存在,变成了全局变量。sum变量同样也变成了全局变量,这种所谓的“变量提升”会消耗一部分无用内存,并对之后的代码编写产生额外的风险。在ES6标准中,新引入块级作用域可以完美地解决这些问题,下一示例中再来研究let与块级作用域。