1、var 定义变量
特点 :①存在变量提升 (即预解析)②函数作用域
代码解释:
//存在预解析
console.log(a);//undefined
var a = 1;
//函数作用域
function fun() {
var a = 10;
if (true) {
var a = 20;
};
console.log(a);//20
};
fun()
2、let定义变量
特点 : ①不存在变量提升②同一作用域内不能重复定义同一个名称③let是块级作用域
代码解释
//1、let 不存在变量提升
console.log(a);//undefined
var a = 1;
console.log(a);//a is not defined
let a = 1;
//2、同一个作用域内不能重复定义同一个名称
var a = 10;
var a = 20;
console.log(a);//20
let a = 10;
let a = 20;
console.log(a);//报错
var a = 10;
let a = 20;
console.log(a);//报错
let a = 10;
a = 20;
console.log(a);//20
let a = 10;
if (true) {
let a = 30;
};
console.log(a);//10 因为a不是在同一作用域内
//3、let块级作用域 var函数作用域
function fun() {
var a = 10;
if (true) {
var a = 20;
};
console.log(a);//20
};
fun()
function fun() {
let a = 10;
if (true) {
let a = 20;
};
console.log(a);//10 let的块级作用域的影响
};
fun()
块级作用域的重要性(可以防止原有的数据被覆盖、篡改) :
//4、块级作用的重要性
for (var i = 0; i < 5; i++) { }
console.log(i); //5
for (let i = 0; i < 5; i++) { }
console.log(i);//报错i is not defined
for (var i = 0; i < 5; i++) {
console.log(i);//0,1,2,3,4,5
}
console.log(i);//5
for (let i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);//i is not defined
//块级作用域的应用
var arr = [];
for (var i = 0; i < 5; i++) {
arr[i] = function () {
console.log(i);
}
};
arr[2]();//5
arr[3]();//5
var arr = [];
for (let i = 0; i < 5; i++) {
arr[i] = function () {
console.log(i);
}
};
arr[2]();//2
arr[3]();//3
arr[4]();//4
注意 :let中常挖的几个坑
//坑1
function f(i) {
let i = 10;
console.log(i);//报错 因为形参相当于var i=100; let i=10;所以会报错
};
f(100)
//坑2
function fun() {
let a = 10;
if (true) {
a = 20;
console.log(a);
let a;//只要在块级作用下let来申明,在当前作用域下不能声明同样的名字
}
};
fun();
//坑3
let a = b, b = 100;
function f() {
console.log(a, b);//报错,b未定义(因为let中不存在变量提升)
}
f();
var a = b, b = 100;
function f() {
console.log(a, b);//100 100
};
f()
3、const定义变量
特点 :除了let所包含的特点外,还另外特有的:①:声明一个只读的常量,一旦声明,常量的值就不允许改变。②一旦声明就必须赋值,否则报错。
const x = 12345;
x = 9999;//error
const y;//errror const一旦声明就必须赋值
注意 :const常挖的坑
//变量obj存储的是一个地址,这个地址指向一个对象,不可变的只是这个地址,即:不能把obj指向另个地 址
//但对象本身是可变的,所以依然可以为其添加值。有点类似于堆和栈
const obj = {};
obj.name = 'abc';
obj['age'] = 18;
console.log(obj);//{name:'abc',age:18}
const obj = { id: 1 };
obj.id = 2;
console.log(obj);
obj = { id: 1 };//obj指向了另一个地址,
console.log(obj);//报错
总结 :
①var为函数作用域,存在变量提升。
②let为块级作用域,不存在变量提升,且同一作用域内不能定义同一名称变量。
③const包含let的所有特点,并且定义的常量值不能修改,一旦定义变量后必须赋初值。