变量提升
首先var声明的是一个全局变量,存在变量提升,那么什么是变量提升呢?在我们js中,代码的执行分成两步(1.预编译 2.自上而下执行):
1.预编译阶段:此时js解析器会找到当前作用域中所有的var、function,将它们放到当前作用域顶上进行提前定义和声明(注意:如果有给变量赋值,赋值操作不会被提前!) ->变量提升机制
例如,以下代码:
console.log(i);
var i = 1;
//输出:undefined
相当于以下代码:
var i;
console.log(i);
i = 1;
如果将var改成let,将会弹出一个错误,例:
console.log(i);
let i = 1;
//报错:ReferenceError: Cannot access 'i' before initialization
//说明let不存在变量提升,需要先声明后使用
2.自上而下执行:此时代码开始一步一步开始执行,遇到函数则进入函数作用域内
作用域
var : 全局作用域、函数作用域,没有块级作用域({})的概念。
let : 块级作用域({}) ,也可以创建全局变量
//例1:
//全局作用域:
for(var i = 0; i<10; i++){
}
console.log(i);
//将i提升至作用域顶端声明 -> 进入for循环,将i赋值为0 ->执行至退出for循环 ->执行console.log
//输出:10
//例2:函数作用域
function fun(){
a = 10;//相当于全局变量
var b = 20;//只在函数内部有效,外部无法访问
}
fun();
console.log(a);//输出10
console.log(b);//报错:ReferenceError: b is not defined
//例3:块级作用域
{
var a = 10;
}
console.log(a);
//输出:10
//不报错,var在块级作用域中声明的变量在全局有效,
//所以说var是没有块级作用域这个概念的,这没有意义
//例4:let声明块级作用域
{
let a = 10;
}
console.log(a);
//报错:ReferenceError: a is not defined
//块级作用域,以外的地方无法访问它
//例5:let声明全局作用域
let a = 10;
{
console.log(a);//输出10
}
function s(){
console.log(a);//输出10
}
s();
console.log(a);//输出10
//let在这里声明的是一个全局变量
重复声明
var: 可以多次声明
let: 不允许重复声明,在相同作用域内不能重复声明
//例1:var重复声明
var a = 10;
function s(){
console.log(a);//输出undefined
var a = 11;
console.log(a);//输出11
}
s();
console.log(a);//输出10
var a;
console.log(a);//输出10
var a = 12;
console.log(a);//输出12
//例2:let重复声明
let a = 1;
{
let a = 1;
console.log(a);//输出1,a声明的作用域不同
}
//例3:
let a = 1;
{
var a = 1;
console.log(a);//报错:SyntaxError: Identifier 'a' has already been declared
}
//例4:
{
let a = 1;
let a = 2;
console.log(a);//报错:SyntaxError: Identifier 'a' has already been declared
}
总结
区别:
- let不存在变量提升
- 块级作用域问题
- 暂时性死区(let)
- 不可重复声明
js初学者,文章有误还望各位大佬多多指正