你胸大你先说:变量提升
场景引入:一个屋子里,不管进门的顺序如何,如果有胸大腰细的妹子,总是有最先说话的权利。
场景类比:一段代码内,不管声明的顺序如何,显式声明的变量和函数,总是会被提到最前解析。
这次要介绍的同样是js世界很奇怪的现象:变量提升。定义如下:
Hoisting is JavaScript's default behavior of moving declarations to the top.
提升是js的默认行为,它把声明(变量或函数)移动到(当前作用域的)最顶
一般计算机语言,有“先声明再使用”的规则。但是对于js,在同一个作用域内,不管声明放在哪个位置,总会自动被放到最前,比如:
cup = 'C';
console.log("cup: " + cup);//cup: C
var cup;//全局的罩杯会被提升到最前
function hoisting(){
if(!cup){
cup = 'D'
}
console.log("cup: "+cup);
var cup;//这个优先被解释
}
hoisting(); //cup: D
//你得罩杯提升啦,开心吗?
要注意的是,被提上来的仅仅是声明,而不是初始化(赋值),对它赋值是不能够被提前的,比如:
function hoisting2(){
console.log("cup: "+cup);
var cup = 'E';//你在想E罩杯岂不是更好?
}
hoisting2();//cup: undefined
//很遗憾,你隆胸失败啦,并且变回了飞机场
而函数声明同样会被提前,让人欣慰的是,函数体同样会被提前。 这个大家想必已经灰常熟悉了,但也还是展示个例子吧:
hoisting3(); //做妹子不能太贪心,好啦,D-cuo还给你
function hoisting3(){
cup = 'D';
console.log("cup: "+cup);//cup: D
}
顺便提一下作用域:在JavaScript中,一个作用域(scope)中的名称(name)有以下四种:
1. 语言自身定义(Language-defined): 所有的作用域默认都会包含this和arguments。
2. 函数形参(Formal parameters): 函数有名字的形参会进入到函数体的作用域中。
3. 函数声明(Function decalrations): 通过function foo() {}的形式。
4. 变量声明(Variable declarations): 通过var foo;的形式。
前两点,this和参数放置最前,这毫无疑问。 而对于后面两点,应该是ECMA规范,所以js就这么设计的。
了解这个的意义是啥?
我们在编码时,都应该把var声明放在代码的最前,并且同时初始化。如此,又让代码优雅,又不会出现不必要的麻烦。