ECMAScript6新属性方法等

ECMAScript6中添加了一些新的结构、属性、方法等,下面将进行简单的说明。

Symbol

ES5的对昂属性名都是字符串,容易造成属性名的冲突。ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,它是JavaScript的第七种数据类型,通过Symbol函数生成。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。如下:

1
2
3
4
5
6
7
8
var mySymbol = Symbol();
var a = {[mySymbol]: 'Hello!'}; //symbol属性不能使用.运算符
a[mySymbol] //"Hello!" symbol属性不能使用.运算符

var s1 = Symbol.for('foo'); //必须都是用for,且输入值相同,才相等
var s2 = Symbol.for('foo');
s1 == s2 //true 使用symbol.for可以实现两个symbol相同
Symbol.keyFor(s2) //"foo" sysmol.for()有登记制,symbol()没有,登记的会返回字符串参数

Set和Map数据结构

Set结构

ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set的方法有四个:set.add(value)、set.delete(value)、set.has(value)、set.clear()清除所有成员。如果要读取或者遍历可以将set通过Array.from(set)转换为数组。

1
2
3
4
5
6
var set = new Set([1,2,3,3,4,"4",NaN,NaN]);
alert(set.size); //6 在set内部,4不等于“4”(不会发生类型转换),NaN等于NaN,对象总是不等于对象{}不等于{}

function dedupe(array){ //数组去重的方法
return Array.from(new Set(array));
}

WeakSet

WeakSet与Set类似,也是不重复的值的集合,但是它与Set有两个区别。一、WeakSet的成员只能是对象。二、WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用。无法引用WeakSet的成员,因此WeakSet是不可遍历的。

1
2
var a = [[1,2],[3,4]]; //数组的成员只能是对象,不能是变量
var ws = new WeakSet(a);

Map结构

JavaScript的对象(Object),本质上是键值对的集合(Hash结构),但是只能用字符串当作键。ES6提供了Map数据结构,类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键,是一种更完善的Hash结构实现。
Map原生提供三个遍历器生成函数和一个遍历方法。entries()、keys()、values()、forEach()。
Map可以与数组、对象、Json相互转换。

1
2
3
4
5
6
7
8
9
10
var m = new Map();
var o = {p:"hello tecent"};
m.set(o,"content");
m.get(o); //"content"

m.size //1
m.has(o); //true
m.delete(o); //true
m.has(o); //false
m.clear(); //全部清空

WeakMap

WeakMap与Map结构基本类似,唯一的区别是它只接受对象做为键名(null除外),而且键名所指向的对象,不计入垃圾回收机制。其设计目的在于,键名是对象的弱引用。

Iterator遍历器与for…of循环

JavaScript原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6又添加了Map和Set。Iterator的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费。其遍历过程如下:

  1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

Iterator接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for…of循环。当使用for…of循环遍历某种数据结构时,该循环会自动去寻找Iterator接口。在ES6中,有三类数据结构原生具备Iterator接口:数组、某些类似数组的对象(字符串等)、Set和Map结构。另外,也可以手动为对象等添加Iterator接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let arr = ['a', 'b'];
let iter = arr[Symbol.iterator](); //默认的Iterator接口部署在数据结构的Symbol.iterator属性
iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: undefined, done: true }

let arr =['b','c'];
['a',…arr,'d'] //['a','b','c','d'] 扩展运算符会调用默认的iterator接口

var arr = ['a', 'b', 'c', 'd'];
for (let a in arr) { //for in循环,只获得对象的键名
console.log(a); // 0 1 2 3
}
for (let a of arr) { //for of循环,获得对象的键值,只返回具有数字索引的属性
console.log(a); // a b c d
}

var map = new Map();
for(var [name,value] of map)