读阮一峰ES6笔记1:let 和 const 命令
let命令
基本用法
ES6 新增了let
命令,用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。
for
循环的计数器,就很合适使用let
命令。
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
//E5用var 结果就是10
//变量i
是let
声明的,当前的i
只在本轮循环有效。每一次循环的i
其实都是一个新的变量,所以最后输出的是6。 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量
i
时,就在上一轮循环的基础上进行计算。
用ES5如何正确实现?(梁涛注)
var a = []; for (var i = 0; i < 10; i++) { a[i] = (function (i) { return function(){ //闭包 console.log(i); } })(i);//立即执行函数 } a[6](); // 6
//运行步骤:先把a[0]到a[9]全部赋值一遍(返回闭包),存于内存中。当执行到a[6]()时,输出结果。
//闭包容易导致内存泄露
不存在变量提升
var
命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined
。
let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
console.log(a) // ReferenceError: a is not defined. (梁涛注)实际运行结果也是undefined。只有let a在对象内部时,在外面调用a,才会报ReferenceError错误。
console.log(b) // undefined
let a = 10; var b = 1;
不允许重复声明
let
不允许在相同作用域内,重复声明同一个变量
// 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; } function func(arg) {//不能在函数内部重新声明参数 let arg; } func() // 报错
块级作用域
块级作用域的出现,实际上使得获得广泛应用的匿名立即执行函数表达式(匿名 IIFE)不再必要了。
// IIFE 写法 (function () { var tmp = ...; ... }());
ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。
// 报错 if (true) let x = 1; //正确写法 if(true){let x=1}
const命令
基本用法
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
const
一旦声明变量,就必须立即初始化。
const
的作用域与let
命令相同:只在声明所在的块级作用域内有效。
const
声明的常量,也与let
一样不可重复声明。
ES6 声明变量的六种方法
ES5 只有两种声明变量的方法:var
命令和function
命令。ES6 除了添加let
和const
命令,还有import
命令和class
命令。
顶层对象的属性
顶层对象,在浏览器环境指的是window
对象,在 Node 指的是global
对象。ES5 之中,顶层对象的属性与全局变量是等价的。
ES6 为了改变这一点,一方面规定,为了保持兼容性,var
命令和function
命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let
命令、const
命令、class
命令声明的全局变量,不属于顶层对象的属性。
var a = 1; // 如果在 Node 的 REPL 环境,可以写成 global.a // 或者采用通用方法,写成 this.a window.a // 1 let b = 1; window.b // undefined