ECMAScript6-let和const命令

大致介绍
ES6是下一代的JavaScript语言的标准,目标是让JavaScript可以用来编写大型的复杂程序,成为企业级开发语言,要查看浏览器对ES6的支持程度可以用阮一峰大佬写的工具ES-Checker
安装:(需要安装npm(心累),推荐用cnpm)
npm install -g es-checker
es-checker
效果(有具体的支持情况):


let
let命令,和var的作用一样,都是用来声明变量,只是let命令只在所在的代码块内有效
经典的例子:

var a = [];
for(var i=0;i<10;i++){
a[i] = function(){
console.log(i);
}
}
a[4](); //10
console.log(i); //10

经典的例子,就不赘述,这里a数组都是引用的同一个i
改用 let:

var a = [];
for(let i=0;i<10;i++){
a[i] = function(){
console.log(i);
}
}
a[4](); //4
console.log(i); // ReferenceError: i is not defined

这里i用let声明,就只在本次循环中存在,每次循环都会创建一个i
注意:在for循环中,循环语句是一个作用域,而循环体内部又是一个子作用域
例如:

for(let i=0;i<3;i++){
let i = 'abd';
console.log(i);
}
//abd
//abd
//abd

可以看出循环体内的i和循环语句中的i是分离的
let的特点
1、不存在变量提升

console.log(a);//undefinedvara = '123';
console.log(b);
let b= '123';//ReferenceError: b is not defined

2、暂时性死区
如果在一个块级作用域内有let命令,那他声明的变量就绑定这个块级作用域,不受外部的影响

var a = '123';
if(true){
a = '456';
console.log(a); //ReferenceError: a is not defined
let a;
console.log(a); //undefined
}

ES6明确规定,如果区块中存在let或者const命令,这个区块对这些命令声明的变量,从一开始就形成封闭作用域,凡是在声明之前使用这些变量都会报错
这里a是用let声明的,所以在let声明之前使用a都会报错
3、不能重复声明
let不允许在同一个作用域内,声明同一个变量

//报错
{
var a = '123';
let a = '456';
}
//报错
{
let a = '123';
var a = '456';
}
//报错
{
let a = '123';
let a = '123';
}

注意:在函数内不能重复声明参数

//报错
function test(target) {
let target;
}
//不报错
function test(target){
{
let target;
}
}

在第二个函数里不报错,是应为{}中时一个新的子作用域,和参数target不是在同一个块内了
块级作用域
let为JavaScript新增了块级作用域
使用var是没有块作用域概念的

var a = '123';
if(true){
var a = '456';
}
console.log(a); //456

使用let就有了块作用域

let a = '123';
if(true){
let a = '456';
}
console.log(a); //123

外层的代码块不受内层代码块的影响
块级作用域和函数声明
ES5规定函数只能在顶层作用域和函数作用域中声明,不能在块作用域中声明
ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
例如:

function f(){
console.log('out');
}
(function(){
if(false){
function f(){
console.log('in')
};
};
f();
}());

在ES5中结果是 'in'。就是函数声明提升,不在多赘述
在ES6中,理想的结果是'out',但是在浏览器中运行时,却会报错,这是为什么?因为如果这么突兀,那么老的代码就会出现很多的问题,所以,ES6规定浏览器可以有自己的的行为方式
1、允许在块级作用域内声明函数。
2、函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
3、同时,函数声明还会提升到所在的块级作用域的头部。
注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。
在ES6中实际执行的代码是

function f(){
console.log('out');
}
(function(){
var f = undefined;
if(false){
function f(){
console.log('in')
};
};
f();
}());

注意:ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。

// 不报错
'use strict';
if (true) {
function f() {}
}
// 报错
'use strict';
if (true)
function f() {}

const命令
const声明一个只读的常量,一旦声明,常量的值就不能改变。所以在使用const时,一旦声明就要立即初始化
const和let一样,只存在与本块作用域中,没有声明提升,存在暂时性死区,不可重复声明
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
例如:

const a = {
id: 1,
name:'qqqq'
};
a.id = 2;
a = {}; //报错

参考资料:
ECMAScript 6入门-阮一峰
博客地址:www.cnblogs.com/qqandfqr

你可能感兴趣的:(ECMAScript6-let和const命令)