本博文是作者学习了ES6的笔记,如有对基础知识有需求的同学可以查看阮一峰老师的ES6基础知识。
1. let命令
for (let i = 0; i < 10; i++) { // ... } console.log(i); // ReferenceError: i is not defined
//let的变量只在for循环的块级作用域里有效。
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
如果是var声明的计数器,var没有块级作用域,只有函数作用域和全局作用域。所有的i都是指向全局变量i的一个引用,所以当代码块执行完毕,所有的i都指向同一块内存,即全局变量i。故输出都是最后一轮的值10。
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
如果是let声明的计数器,let有块级作用域,当前的i
只在本轮循环有效,所以每一次循环的i
其实都是一个新的变量,所以最后输出的是6
。Javascript引擎内部会记住上一轮循环的值,初始化本轮的变量i
时,就在上一轮循环的基础上进行计算。
for (let i = 0; i < 3; i++) { let i = ‘abc‘; console.log(i); } // abc // abc // abc
//输出了3次abc
注意,循环变量部分是父级作用域,循环体内部是子作用域。即两个变量分别属于不同的作用域。
// var 的情况 console.log(foo); // 输出undefined var foo = 2; // let 的情况 console.log(bar); // 报错ReferenceError let bar = 2;
ES6 明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
在代码块内,使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
var tmp = 123; if (true) { tmp = ‘abc‘; // ReferenceError let tmp; }
//后声明变量,报错 typeof x; // ReferenceError let x;
//如果一个变量根本没有被声明,使用typeof反而不会报错。
typeof undeclared_variable // "undefined"
function bar(x = y, y = 2) { return [x, y]; } bar(); // 报错 function bar(x = 2, y = x) { return [x, y]; } bar(); // [2, 2] // 不报错 var x = x; // 报错 let x = x; // ReferenceError: x is not defined
let
、const
语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免此类错误就很容易了。总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。2. const命令
const命令主要用于声明一个只读的常量。一旦声明,常量的值就不能改变。
(后续继续补充)
原文:https://www.cnblogs.com/gerryzhang/p/10590551.html