“变量声明”你真的会吗?
一、变量声明提升
例题1
console.log(a)
var a=3;
打印结果
undefined
考点:var声明的变量可以将声明提升
例题2
var a =3;
function fn(){
console.log(a);
var a = 4;
}
console.log(a)
fn()
打印结果:
3
undefined
考点:var声明的变量可以将声明提升&函数作用域
本题fn作用域内存在a变量,在执行fn内部代码前将a的声明提升,执行fn内部的代码时直接使用fn作用域内的a,所以不会根据作用域链向上查找
例题3
var a =3;
function fn(){
console.log(a);
var a = 4;
console.log(a)
}
console.log(a)
fn()
打印结果:
3 //第7行打印
undefined //第3行打印
4 //第5行打印
考点同上题
代码解析:
//主代码块声明提升
var a;
function fn (){console.log(a);var a = 4; console.log(a);}
//1. 执行主代码块内容
a=3; //window作用域内的a被赋值为3
console.log(a);
//2. 主代码块调用fn函数
var a; //执行函数前,将fn作用域内的变量声明提升。
//执行fn内部代码
console.log(a); //此时fn作用域内的a还没有被赋值,值为undefined
a=4;
console.log(a) //此时fn作用域内的a的值被赋为4
例题4
var a = 100;
function foo() {
console.log(a);
return;
var a = 200;
}
foo();
打印结果:
undefined
return 后面的语句不会执行,但是变量声明会被提升
二、函数声明提升&变量声明提升
例题1
function a(){}
var a;
console.log(a);
打印结果:
ƒ a(){}
考点:声明提升的优先级
声明提升的优先级:函数的声明提升>变量的声明提升
所以a最终被声明为函数
例题2
function a(){}
var a=2;
console.log(a);
打印结果:
2
考点:var声明的变量可以重新赋值
虽然函数的声明提升>变量的声明提升,但是在执行代码过程中,a被重新赋值成了2
例题3:综合题
fn()
var a =3;
var fn=6;
function fn(){
console.log(a);
var a = 4;
console.log(a)
}
console.log(a)
console.log(fn)
打印结果:
undefined
4
3
6
考点:声明提升优先级&var声明的变量重新赋值
例题4:综合题
fn()
var a =3;
var fn=6;
function fn(){
console.log(a);
var a = 4;
console.log(a)
console.log(fn)
}
console.log(a)
console.log(fn)
打印结果:
undefined
4
ƒ fn(){ console.log(a);var a = 4;console.log(a);console.log(fn) }
3
6
综合考点:声明提升&作用域链&重新赋值
代码解析:
//window作用域的变量提升
var a;
fn(){...}
//执行主代码块
调用fn,fn作用域内的变量提升
var a;
执行fn内部代码
console.log(a); //fn作用域内的a还没有被赋值
a=4;//将fn作用域内的a赋值为4
console.log(a) //fn内的a已被赋值为4,打印出4
console.log(fn) //fn作用域内没有fn变量,向window作用域查找,找到函数fn并打印
//fn调用结束,主代码块继续向下执行
a=3;//将window作用域内的a赋值为3
fn=6;将window作用域内的fn赋值为6
console.log(a) //打印window作用域内的a
console.log(fn) //打印window作用域内的fn
三、变量提升&let
例题1
var a =3;
function fn(){
console.log(a);
let a = 4;
console.log(a)
}
fn()
console.log(a)
打印结果:
Uncaught ReferenceError: Cannot access 'a' before initialization
考点:let定义的变量声明不会被提升
fn作用域内存在变量a,但是a的声明不能被提升,而变量不声明直接使用就会报错