一、 声明提升
声明提升是JavaScript中的一个缺陷,会造成输出结果与所构想的结果不一致。
1. js引擎会将简写形式分解为原形式
2. 将找到的声明依次提前到当前作用域的顶部,集中创建,
3. 赋值将会留在原地
例如:
var a = 10;
=>
var a; a= 10;
在程序开始执行前,找两种东西:
var 变量名;
function 函数名(…){…}
1.1 示例讲解(变量提升)
示例代码:
//var a //会将第三行的var a提到最前面,提前声明变量
console.log(a); //undefined
var a = 1; //有var才提升
console.log(a); //1
①第一步将var a = 1;
的简写形式分解为声明语句和赋值语句
②将声明提升到当前作用域的顶部:
③所以当执行到第一句console.log(a)
时,a还未赋值,故为undefined
③当执行到第二句console.log(a)
时,a已被赋值1,故为1
1.2 示例讲解(函数提升)
示例代码:
function fun(){console.log(1);}
fun();
function fun(){console.log(2);}
fun();
①首先找到两个function fun(){},将其提到当前作用域的顶部:
②顶部的两个fun()函数同名,后添加的覆盖前一个,故fun()输出的都是2
二、解决方案
针对1.2的示例代码,我们原意是要输出1,2,由于js的声明提升缺陷,输出结果为2,2。
如何解决这个问题呢?
2.1 使用赋值
“js引擎会将简写形式分解为原形式” “赋值将会留在原地”
代码如下:
var fun = function fun(){console.log(1);}
fun();
var fun = function fun(){console.log(2);}
fun();
详解
①var fun = function fun(){console.log(1);}
为简写形式,可分解:
②将var fun;
提到当前作用域的顶部
③同理,第二个var fun语句重复上述操作
④顶部语句覆盖:
⑤js引擎进行赋值,首先赋值fun = function(){console.log(1)}
,故第一个fun()结果返回1
⑥往下走,赋值fun = function(){console.log(2)}
,故第二个fun()值为2
三、exercise
例1:
function fn() {
//var b 提升到整个函数作用域的最前边
console.log(b);//undefined
var b = 2;
console.log(b);//2
}
fn();
例2:
var c = 3;
function fun() {
//var c;
console.log(c); //undefined
var c = 5; //给当前作用域下的c赋值给5
}
fun();
console.log(c); //3