《ECMAScript 6 入门》let和const

let 命令

let 命令,用来声明变量。类似 var,但是只在 let 命令所在的代码块内有效。

{
  let a = 10;
  var b = 1;
}

a // ReferenceError: a is not defined.
b // 1

for 循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

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

上面代码输出3次 abc。表明代码块内容变量 i 与循环变量 i 不在同一个作用域,有各自单独的作用域。

不存在变量提升

var 命令会发生“变量提升”现象,即变量可以在声明之前使用,值为 undefined
let 改变了语法行为,一定先声明后使用。

暂时性死区

只要块级作用域内存在 let 命令,它所声明的变量就“绑定”这个区域,不再受到外部影响。

var tmp = 123;
if (true) {
  tmp = 'abc'; //ReferenceError
  let tmp;
}

** ES6 明确规定,如果区块内存在 letconst 命令,这个区块对这些命令声明的变量形成封闭作用域。 **

typeof 不在是一个安全的操作

typeof x; //ReferenceError
let x;

如果一个变量没有被声明,不会报错。

不允许重复声明


块级作用域

ES6 的 let 为 JavaScript 新增了块级作用域。
允许块级作用域的任意嵌套。
外层作用域无法读取内层作用域的变量。
内层可以定义外层同名的变量。

do 表达式

块级作用域是一个语句,讲多个操作封装在一起,没有返回值。
现在有一个提案,使它变为 do 表达式。

let x = do {
  let t = f();
  t * t + 1;
}

上面代码,变量x会得到整个块级作用域的返回值。


const命令

const 声明一个只读的常量。一旦声明,值不能改变。

本质

const 保证的是变量指向的内存地址不得改动。
当地址指向一个对象时,对象本身是可变,可以添加新属性。
如果真的想将对象冻结,可以使用 Object.freeze 方法。

const foo = Object.freeze({});

// 常规模式时,下面一行不起作用;
// 严格模式时,改行会报错
foo.prop = 123;

除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  })
}

ES6声明变量的六种方法

varfunctionletconstimportclass

顶层对象的属性

ES5时,浏览器中的顶层对象指的是 window,Node指的是 global 对象。
ES6为了改变这一点,varfunction 命令声明和ES5保持一致,let 命令、const 命令、class 命令声明的全局变量,不属于顶层对象的属性。

你可能感兴趣的:(《ECMAScript 6 入门》let和const)