思维导图
基本用法
{ let a = 10; var b= 1; } console.log(a) // error console.log(b) // 1
let 很适合用在 for
循环中的计数器
不存在变量提升
console.log(foo); // ReferenceError let foo = 10; // typeof 将不再是一个百分百安全的操作 typeof x ; // ReferenceError let x;
暂时性死区 (TDZ temporal dead zone)
只要块级作用域内存在 let
命令,它所声明的变量就 "绑定" 这个区域,不再受外部的影响
var tmp = 123; if(true){ // TDZ 开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ 结束 }
不允许重复声明
let 不允许在相同作用域内重复声明同一个变量
// 报错 function() { var a = 10; let a = 10; } // 报错 function() { let b = 10; let b = 10; } // 报错 function(arg) { let arg ; } // 不报错 function(arg) { { let arg ; } }
块级作用域的出现让广泛应用的 IIFE 不再必要了
// IIFE 写法 (function(){ var tmp = ''; .... })() // 块级作用域写法 { let tmp = ''; .... }
块级作用域外部无法调用块级作用域内部的函数
{ let a = 'aaa'; function f() { return a; } } f() // 报错
这样来处理
let f; { let a = 'aaa'; f = function() { return a; } } f() // 'aaa'
声明常量
const一旦声明就必须立即初始化,不能留到以后赋值。
const foo; // SyntaxError: missing = in const declaration
const 复合型变量
变量名不指向数据,而是指向数据所在的地址。
const foo = {}; foo.prop = 123; foo.prop; // 123 foo = {}; // 报错 read-only
真想冻结对象 可用 freeze 方法
const foo = Object.freeze({});
const声明的常量只在当前代码块有效。如下方法来跨模块:
//constants.js 模块 export const A = 1; export const B = 2; export const C = 3; // test1.js 模块 import * as constants from './constants'; console.log(constants.A); // 1 console.log(constants.B); // 2 // test2.js 模块 import {A, B} from './constants'; console.log(A); // 1 console.log(B); // 2
ES6中规定
var a = 1; window.a; // 1 let b = 1; window.b; // undefined