ES6相关特性的整理(变量&数据结构)

226 阅读4分钟

  早前,读了阮一峰大神的ES6 入门,想着还是要输出一些东西,决定写下来,博客写得不多,但还是想记录一下,也当是以后给自己看啦。

变量

1. let

  let存在两个主要特点,分别是:不存在变量提升和暂时性死区(如果区块中存在let或者const,这个区块从一开始就形成了封闭作用域。凡是在声明之前使用这些变量,就会报错)
  例子:

 var temp = 123;
 if (true) {
     temp = 'abc';   // Refernce Error
     let temp;
 }

在上述例子中,if语句所在的代码块中因为let的存在,形成一个暂时性死区,因此temp=‘abc’无法对外面的temp进行赋值,与外界变量无关。temp还是一个未声明的变量。因此会报错。

  同时,let不允许在相同作用域内重复声明。
  例子:

 function func(){
     let a = 10;
     var a = 10;
 }

在上述例子中,func函数中对a进行了重复声明,会报错。

  最后,let所在的代码块会形成一个块级作用域。   例子

 function func(){
     let n = 5;
     if(true) {
         let n = 10;
     }
     console.log(n)    //5
 }

因为在if所在的代码块中形成了块级作用域,所以js引擎在查找n的值时,只会沿作用域链向上查找,而不会向下查找。因此n的值为5而不是10。

2. const

使用const声明变量最大的特点就是声明的变量不得改变值,一旦声明,必须初始化。这里所说的“不得改变”本质上是指变量指向的内存地址不得改动。
但是,复合型数据(对象和数组),它们指向的内存地址保存的是一个指针,只能保证指针是不变的。

 const foo = {};
 foo.prop = 123;   //成功
 foo = {};        //报错

在上述例子中,变量foo是一个对象,因此内存中所保存的是该变量的地址,只要保证地址不变即可。所以对foo的属性赋值是可以成功的,因为没有改动foo变量本身的地址。

** 需要注意的是,let、const、class命令声明的全局变量都不属于顶层对象的属性。

3. 变量的结构赋值

变量的架构赋值主要是针对对象和数组,以key为查找对象,没有查找到的为undefined。
例子:

 let [x, y, z] = [1, 2, 3];
 let [head, ...tail] = [1, 2, 3]            // head = 1, tail = [2, 3]
 let [a, b, c, d, e] = 'hello'             //a = 'h', b = 'e', c = 'l', d = 'l', e = 'o'
 let {foo, bar} = {foo: 'a', bar: 'b'}    //foo = 'a', bar = 'b'
 let {foo: baz, bar: last} = {foo: 'a'}   //baz = 'a', last = undefined

主要的应用场景有:
  1. 交换变量的值:

   let x = 1;
   let y = 2;
   [x, y] = [y, x];    //x = 2, y = 1

  2. 从函数返回多个值时,取值方便

  let example = () => [1, 2, 3];
  let [a, b, c] = example();   // a = 1, b = 2, c = 3

  3. 提取JSON数据

  let jsonData = {id: 42, status: 'ok'};
  let {id, status: number} = jsonData;    //  id = 42, number = 'ok'

数据类型

Symbol

es6中新增的一种数据类型,表示绝不重复的值。 例子:

  let s1 = Symbol(33);
  let s2 = Symbol(33);
  console.log(s1 == s2)   //false
  
  let s3 = 2;
  let s4 = 2;
  console.log(s3 == s4)   //true

从例子中可以看到,s1与s2并不相等。 应用场景:使用一个他人提供的对象时,但又想为这个对象添加新方法,新方法可能与现有方法冲突,可以使用Symbol,保证不会与其它属性冲突。

数据结构

es6中针对数组和对象分别新增了不同的数据结构。这里我只粗略介绍一下特点和应用场景。

1. Set

新的数据结构,类似于数组,但set里的值是不会重复的。
应用场景:数组去重( array = [ ... new Set( array )] )

2. WeakSet

成员只能是对象,同时垃圾回收机制不考虑weakSet中对对象的引用。

3. Map

本质与对象一样,但key可以是各种类型的值(包括对象),而对象中的key是字符串。

4. WeakMap

只接受对象作为键名,同时键名所指向的对象不计入垃圾回收机制。 应用场景:想要给某个DOM元素添加数据时,可以使用WeakMap。这样可以避免在删除该DOM元素后还保存着对它的引用,无法回收内存。