let和const都有块级作用域
块级作用域:简单理解就是一个大括号就是一个块
es5定义的变量
if(false) {
var a = 100;
}
console.log(a) // undefined
undefined不是错误,而是一种特殊的数据类型,是合法的,允许存在的,所以就说明一个问题,if语句的括号没有限制住a的作用域,所以我们可以这么认为var定义的变量是没有块级作用域的
es6中let和const的定义的变量
//let定义的变量
if(true) {
let b = 200;
}
console.log(b) //报错
// const定义的变量
if(false) {
const c = 300;
}
console.log(c) //报错
let和const定义的变量,无论if条件中为true或者false,内部的括号都会封闭自己的作用域
let和const定义的变量有一个特点,就是在哪一级定义的,就在哪一级使用,因为有自己的块限制
小案例:不仅if条件语句可以作为块级作用域,循环语句也可以
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
如果使用let
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
let和const声明的变量都没有声明提升
es5变量的声明是可以提升的
console.log(a) // undefined
var a = 100;
//等价于
var a;
console.log(a) // undefined
a = 100;
a会返回undefined,并不会报错,那是因为a此时已经定义了,并且提升到了当前作用域(全局作用域或者函数的作用域)的最顶部
let和const声明变量
// let 声明
console.log(b) // 报错
let b = 200;
// const 声明
console.log(c) // 报错
const c = 300;
let和const不能进行变量声明提升,必须在变量的声明后进行使用
let和const是会出现暂时性死区
var 定义的变量
var tmp = 123;
if (true) {
tmp = 'abc';
var tmp;
}
这么写并不会报错 再看 let 和 const
// let 定义
var tmp = 123;
if (true) {
tmp = 'abc'; // 报错
let tmp;
}
// const 定义
var tmp = 123;
if (true) {
tmp = 'abc'; // 报错
const tmp;
}
报错
重复定义 也会报错
{
var a = 100;
let a = 200;
}
暂时性死区和重复定义有着一定关联关系,暂时性死区和重复定义变量都是需要避免,会报错影响程序主流程
let定义的是变量,const定义的是常量
let a = 100;
a = 200;
console.log(a)//200
const b = 100;
b = 200;
console.loh(b)//不是输出100而是报错
所以你会发现const定义的是常量,常量是不允许修改的,比如定义一个基数(PI)const PI = 3.1415926…这个PI常量就一定不能修改
let和const定义的全局变量不是window的属性
es5 定义的全局变量是window的属性
var a = 100;
var b = window.a;
console.log(b);//100
let 和 const定义的全局变量不会成为window的属性
let a = 12345;
console.log(window.a) // undefined