初探Es6

背景:最近搞react得过程中,一直会接触到es6的语法,看来很有必要学习和研究一下啊。

一、let和const

  1. ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

  2. let不像var那样会发生“变量提升”现象。所以,变量一定要在声明后使用,否则报错。

  3. 在块级作用域内,使用let命令或者const命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ)。

  4. 既然出现了TDZ,那也意味着typeof不再是一个百分之百安全的操作。如果在死区内使用typeof则会抛出一个ReferenceError错误(注意typeof操作符如果返回undefined表示的是未定义,并不算报错)。

  5. let不允许在相同作用域内,重复声明同一个变量。

  6. es6实际上增加了一个块级作用域(以前只有全局作用域和函数作用域),另外,ES6也规定,函数本身的作用域,在其所在的块级作用域之内。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function f() { console.log('I am outside!'); }
    (function () {
    if(false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
    }
    f();
    }());

    结论:es6之前,得到的结果是’inside’,因为不管进不进的了if,函数申明都会被提到当前作用域的顶部,而在es6中,得到的结果是’ouside’,不管会不会进入if代码块,其内部声明的函数皆不会影响到作用域的外部。

  7. const声明是常量。一旦声明,常量的值就不能改变。在'use strict'模式下,改变常量的值会报错。注意,如果是常规模式,对常量赋值不会报错,但也是无效的。

  8. const的作用域与let命令相同:只在声明所在的块级作用域内有效。const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。const声明的常量,也与let一样不可重复声明。

  9. 对于const命令申明的复合类型的常量,常量名不指向数据,而是指向数据所在的地址。const命令只是保证常量名指向的地址不变,并不保证该地址的数据不变。

    • 定义对象

      1
      2
      3
      4
      5
      6
      7
      const foo = {};
      foo.prop = 123;
      foo.prop
      // 123
      foo = {} // TypeError: "foo" is read-only
    • 定义数组

      1
      2
      3
      4
      const a = [];
      a.push("Hello"); // 可执行
      a.length = 0; // 可执行
      a = ["Dave"]; // 报错

      如果真的想将对象冻结,应该使用Object.freeze方法:

      1
      2
      3
      4
      5
      const foo = Object.freeze({});
      // 常规模式时,下面一行不起作用;
      // 严格模式时,该行会报错
      foo.prop = 123;
  10. varfunction定义的全局变量实际上是全局对象的属性,而letconst定义的变量则不能通过全局对象的属性的形式来用,否则会报出undefined

二、变量的解构赋值

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

数组的解构赋值

完全解构

以前数组的赋值只能这样做

1
2
3
var a = 1;
var b = 2;
var c = 3;

现在可以通过解构赋值

1
var [a, b, c] = [1, 2, 3];

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

不完全解构

等号左边的模式,只匹配一部分的等号右边的数组。

1
2
3
4
5
6
7
8
let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

允许有默认值

触发默认值必须要返回一个undefined菜有效,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

1
2
3
4
5
6
7
8
9
10
11
var [foo = true] = [];
foo // true
[x, y = 'b'] = ['a'] // x='a', y='b'
[x, y = 'b'] = ['a', undefined] // x='a', y='b'
var [x = 1] = [undefined];
x // 1
var [x = 1] = [null];
x // null

对象的解构赋值

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

字符串的解构赋值

数值和布尔值的解构赋值

函数参数的解构赋值

解构赋值的用途