变量提升
js执行过程分为两个阶段
- 词法分析:词法分析主要包括:分析形参、分析变量声明、分析函数声明三个部分。通过词法分析将我们写的js代码转成可以执行的代码
- 执行阶段
- 变量提升
var a=18;
fun1();
function fun1(){
var b=9;
console.log(a);//undefined
console.log(b);//9
var a="123";
}
console.log(a);//18
第一、根据就近原则,局部变量和全局变量同名时,优先使用局部变量;第二、在fun1函数体内变量a的声明被提到了函数体里作用域的顶端,上面代码编译后应该是下面这个样子
fun1();
function fun1(){
var a;
var b=9;
console.log(a);//undefined
console.log(b);//9
a="123";
}
var a=18;
console.log(a);
- 函数提升
具名函数的声明有两种方式:函数声明式和函数字面量式
function bar(){} //函数声明式
var fun1=function(){} //函数字面量式
函数字面量式的声明和变量提升的结果是一样的,函数只是一个具体的值;
但函数声明式的提升现象和变量提升略有不同,函数声明式会提升到作用域最前边
console.log(bar);
function bar(){
console.log(1);
}
//输出结果
//function bar(){
// console.log(1)
//}
console.log(bar); //undefined
var bar=function(){
console.log(1);
}
foo();//1
var foo;
function foo(){
console.log(1);
}
foo=function(){
console.log(2);
}
foo() //2
小题
1.函数与变量同名时,以函数为准
console.log(a);
var a=1;
function a(){
return "sss";
}
//输出结果为
//f a(){return "sss";}
function f(a,b){
console.log(a) //10,声明提升
var a=100;
}
f(10,5)
3.变量没声明,不会提升
console.log(a);//undefined
var a=100;
console.log(b); //报错,因为没有对b声明
b=10
F1() //1
function F1(){
alert('1')
}
F2(); //报错,声明提升F2提到前面不是一个函数,而是变量
var F2=function(){
alert('2')
}
alert(a);//undefined
alert(b);//undefined
alert(c);//报错
alert(d);//报错
var a=1;
if(false)
var b=2;
else
c=3;
function f(){
var d=4;
}
f1();
a=1000;
function f1(){
var a=100;
var b=10;
function f2(){
function f3(){
console.log(a); //undefined,
}
var c=200
f3()
var a=50;
}
f2()
}
就近原则,f3()后面的变量a的声明提升,上面的代码编译后应该是这个样子的
f1();
a=1000;
function f1(){
var a=100;
var b=10;
function f2(){
var a;
function f3(){
console.log(a); //undefined,
}
var c=200
f3()
a=50;
}
f2()
}
总结
- 就近原则:局部变量和全局变量同名时,优先使用局部变量
- 所有的声明都会提升到作用域的最顶端
- 同一个变量只会声明一次,其他的会被忽略或者覆盖掉
- 函数声明的优先级高于变量声明的优先级,并且函数声明和函数定义的部分一起被提升