Hegwin.Me

无边落木萧萧下,不尽长江滚滚来。

学习ES2015 Part 3

Array 新特性

Array Destructing

感觉这也是从Ruby或者类似的语言学习过来的方法,在ES5,我们没有办法直接把数组的各个值一次性赋给多个变量,而现在我们可以了,假设我们有这么一个数组:

let users = [ 'Hegwin', 'Jason', 'Ken' ];

如果我们想直接把users的三个元素依次复制给三个变量,那我们就可以这样:

let [ a, b, c ] = users;
// a => "Hegwin", b => "Jason", c => "Ken"

同时,我们也可以忽略掉数组中的部分元素:

let [ a, , b ] = users;
// a => "Hegwin", b => "Ken"

我们也可以使用延展方法(spread):

let [ first, ...rest ] = users;
// first => "Hegwin"
// rest => ['Jason', 'Ken' ]

这三个点表示把数组中剩余的部分,以数组的形式复制给rest变量。

for ... of 循环

还是这个数组 let names = [ 'Hegwin', 'Jason', 'Ken' ] ,如果我们需要循环依次取出数组的元素,在ES5中,我们需要使用for ... in 循环,就像这样:

for (let index in names) {
  console.log(names[index]);
}

而在ES2015中,我们可以利用for ... of循环直接在循环时取出元素本身,而不再需要通过下标去取:

for (let name of names) {
  console.log(name)
}

Array的find方法

假设我们有这么一个数组,里面有三个对象:

let users = [
  { login: 'Ken', admin: false },
  { login: 'Joe', admin: true },
  { login: 'May', admin: ture },
]

现在我们需要找出第一个admin为true的user,过去我们需要使用循环,要么是js原生的,要么是jQuery或者lodash提供的一些API,而在ES2015中,我们可以使用新增的find方法:

let admin = users.admin((user) => {
  return user.admin;
})

这里用到了 => 语法,我们也可以写的更简单:

let admin = users.find( user => user.admin );

新的数据结构 Map

Map 是什么?

Map简单说就是映射,是一种键值对存储数据的结构,那么问题来了,Map和Object有什么区别,各自有什么应用场景?简单说来是这样的:

  1. Object 会强制的将key转换为string,无论这个key原先是什么;

  2. 如果你能预先知道你的key,那么用 Object,如果key的值只有在运行时才能得到,那么则用Map。

对上面简单举个例子说明下:

let array = [1, 2, 3];
let object = {};
object[array] = "Myth";
console.log(object);

let map = new Map();
map.set(array, "Answer")
console.log(map);

输出:

Object {1,2,3: "Myth"}
Map {[1, 2, 3] => "Answer"}

比较一下就可以看到,在Object中,我们尝试用一个数组去做key,结果得到的结果,却是使用了'1,2,3'这个字符串去做的key,而Map中则直接用的原来的结构。

基本操作

说起来的Map的基本操作无非就是:赋值、取值、删除,以及在某些时候我们需要遍历一个Map对象。

前三个方法都很简单,即 set(key, value)get(key)delete(key),而Map的遍历我们可以用for ... of循环:

let map = new Map();
map.set('user', 'Hegwin');
map.set('topic', 'ES2015');
map.set('replies', ['So cool!', 'Wanna have a try']);

for (let [key, value] of map) {
  console.log(`${key}: ${value}`);
}

输出:

user: Hegwin
topic: ES2015
replies: So cool!,Wanna have a try

WeakMap

WeakMap和Map的思想比较相似,但是又有不同:

  1. WeakMap的key必须是一个Object对象

  2. 不能使用for...of 循环需遍历一个WeakMap对象

  3. 在内存上更加高效,Map的key对Object的引用是一个弱引用,在垃圾回收时,如果一个Object仅仅被WeakMap引用,那么这个Object是可以回收的。

注:WeakMap名字的由来,也是由于“弱引用”这个缘故。

新的数据结构 Set

Set顾名思义,即“集合”,它的诞生背景是Array中允许重复的元素,而我们还需要集合这种数据结构,保证其中的元素是唯一的。

Set 的基本方法

  • add(value) : 添加
  • delete(value) : 删除
  • has(value) : 返回true/false,表示Set是否包含这个值
  • clear() : 清除所有元素

举例来说就是这样:

let tags = new Set();

tags.add("JavaScript Programming");
tags.add({ version: "2015"});
tags.add("web");
tags.add("web");

在最后我们尝试两次添加值为"web"的元素,但实际上第二次添加并没有生效:

console.log(tags.size)  // => 3

Set 的遍历

对于Set我们可以采用for...of循环:

for (let tag of tags) {
  console.log(tag);
}

也可以使用类似数组的spread方法:

let [a, b, c] = tags;

WeakSet

WeakSet写在Set之后,其关系和 WeakMap之余Map非常相似。

  1. WeakSet的值不能读取,也不能通过for ... of 循环取出

  2. 只允许添加Object作为元素

  3. 基于以上,常用的方法只剩下#has#delete

  4. 同样是优化了GC时的性能,同WeakMap

Tags:

Posted on: 2016-08-17

Back