1、let命令
基本用法
用来声明变量,类似于var,但是所声明的变量只在let命令所在的代码块内有效。
for循环中适合使用let:
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6]();//6,如果用var声明i,输出会是10。
不存在变量提升
let命令不会提升声明,即先使用后声明不会返回undefined,会直接报错。
// var 的情况
console.log(a); // 输出undefined
var a= 2;
// let 的情况
console.log(a); // 报错
let a= 2;
暂时性死区
当前作用域存在let命令时,其声明的变量将绑定这个区域,不受外部影响,即必须要在声明之后,才能使用此变量,即使它在外部已声明过。
任何在声明语句执行结束前的使用都会报错,包括typeof检测。
其本质是:只要进入当前作用域,所有变量就已存在,但不可获取,只有当声明变量那行代码执行完毕,才可获取和使用。
a=1; // 报错
let a;
typeof a; // 报错
let a; //如果使用的是var,上一行代码会返回undefined
不允许重复声明
let不允许在相同作用域内,重复声明同一个变量。
// 报错
function () {
let a = 10;
var a = 1;
}
// 报错
function () {
let a = 10;
let a = 1;
}
2、块级作用域
ES6 的块级作用域
let实际上为JavaScript新增了块级作用域
function fun() {
let a = 5;
if (true) {
let a = 10;
}
console.log(a); // 5
}
块级作用域的出现,让立即执行行数表达式可以简化:
(function () {
var a = ...;
...
}());
//简化为:
{
let a = ...;
...
}
块级作用域与函数声明
在块级作用域内,应尽量避免声明函数,若必须声明,则应该写成行数表达式,而不是函数声明,因为函数声明会被提升到块级作用域的头部。
(function () {
if (false) {
function f() { console.log('I am inside!'); }
}
f();
}());
//因为函数声明提升,上述代码在ES6中实际相当于:
(function () {
var f = undefined;
if (false) {
function f() { console.log('I am inside!'); }
}
f();//此时f不是一个函数,会报错。
}());
3、const命令
基本用法
const命令声明的是一个常量,一旦声明,就不允许改变。
所以声明时必须初始化,只声明不赋值的const命令会报错。
const声明与let相似:
- 不提升变量。
- 存在暂时性死区。
- 只在声明后使用。
- 只在块级作用域内有效。
- 不可重复声明。
const命令声明对象时,此对象的属性的值依然可改变,对象本身不可改为新对象,声明数组时同理。
const obj= {};
// 为 obj 添加一个属性,可以成功
obj.pro = 123;
obj.pro // 123
// 将 obj 指向另一个对象,就会报错
obj= {};
const a = [];
a.push('Hello'); // 可执行
a.length = 0; // 可执行
a = ['world']; // 报错
4、顶层对象的属性
浏览器环境下顶层对象是指window对象。
var、function声明的全局变量是window对象的属性,let、const、class声明的变量则不是。