ECMAScript 6 – 新对象和现有对象更新 已翻译 100%

oschina 投递于 2015/03/16 16:00 (共 24 段, 翻译完成于 03-21)
阅读 4635
收藏 52
6
加载中

本文是对发布于 DNC 杂志一月版 上的 ES6 系列文章的一个继续。在第一部分中,我们看见了在 ES6 中即将来临的对 JavaScript 语言的一些改进。本文将着眼于新的对象类型,以及对该语言中已经存在的对象的 API 的更新。

就如在 第一篇文章 中已经提及的,ES6 致力于匹配 JavaScript 来使之更适合于编写大规模的应用程序。为了实现该目标,该语言的设计者们已经对其添加了不少的新特性,这些特性的灵感源于那些“有类型(typed)”的 JavaScript 的替代版以及一些其它的库,包括一些服务端的库。以下是关于那些新的和更新过的对象的一瞥:

  • 新的数据结构,用于更简单的储存唯一性的值(Set),或,有唯一性的键的键-值对(Map)

  • 已经存在的对象,比如 Math 和 Number 会获得新的功能来执行更多的操作,和用更优的方式来执行已存在的操作。

  • String 类型将会获得一些使得 “解析(parsing)” 操作更方便的特性。

  • Object 类型将会获得一些函数来 “分配(assign)” 一个对象以及在两个对象之间进行比较。

  • 在 Array 类型上的新函数集现在可以更方便的来查找到一个元素,一个元素的索引,以及在数组内部对元素进行拷贝操作。

  • 新的 Proxy 对象来对以存在的对象或者函数扩展(extend)功能集。

maverickpuss
maverickpuss
翻译于 2015/03/17 11:36
2

为 ES6 API 提供平台支持

这些 API 目前并不完全支持所有的平台。Chrome 和 Opera 最新的版本不支持一些在 String 上的新功能并且根本不支持 Proxy 对象。类似于 traceur 6to5 这样的编译器没有提供polyfill相关的API。我是用Firefox nightly去测试所有的这些例子的。一些脚本为了arrow功能和short hand功能使用ES6的新语法,你最好使用traceur编译脚本。

现在你得到了一个关于ES6 API更新的结论,让我们开始探索他们吧。

溪边九节
溪边九节
翻译于 2015/03/16 21:31
1

SetWeakSet

Set

Set 是一个包含互不相同的值的集合,这些值可以是任何 JavaScript 类型(即Number,Boolean,String,Object等)。它会忽略任何对其插入重复值的尝试。Set 是可迭代的;意思是我们可以在 Set 上用 for…of 循环来遍历。

我们可以通过调用 Set 类型的构造器来创建一个新的 Set 实例,就像这样:

var mySet = new Set(listOfItems);

..其中 listOfItems 是可选参数,它包含一个将要被插入到 Set 中的可迭代的元素列表。如果没有传递这个参数,将会创建一个空的 Set。

下面是一个 Set 对象的例子:

var setOfObjects = new Set([17, 19, 38, 82, 17]);

我们可以在 Set 对象上用 for…of 循环来遍历它,因为 Set 是一个可迭代的对象。下面的代码会打印 Set 内部存储的值:

for (let item of setOfObjects) {
    console.log(item);
}

注意检查这个循环的输出;重复添加到这个 Set 的值是不会显示出来的。在我们这个例子中,“17”只被存储了一次。Set 内部通过使用 SameValueZero(x,y) 来忽略重复的值。

接下来让我们看看 Set 在 API 中提供了哪些方法。

霍啸林
霍啸林
翻译于 2015/03/17 19:52
1

添加元素

元素可以通过 set.add() 方法添加到 Set 中。

setOfObjects.add(4);
setOfObjects.add(45);
setOfObjects.add(18);
setOfObjects.add(45);

第二次尝试将 45 插入到 Set 中的代码无法执行成功,因为 Set 中已经包含了那个值。

验证一个对象的存在性

Set 上的 has() 方法能检查 Set 中是否包含传入的对象。对象是按引用而非值比较的。下面的例子说明了这点:

var obj = {value: 100};
setOfObjects.add(obj);
console.log(setOfObjects.has(obj));          // true
console.log(setOfObjects.has({prop: 100}));  // false
霍啸林
霍啸林
翻译于 2015/03/17 19:13
2

删除对象

存储在Set中的对象,可以通过它们的引用,使用delete() 方法删除,或者使用clear() 方法清除。 下面是一些例子:

setOfObjects.delete(obj);
setOfObjects.clear();

Set的大小

Set的size属性包含了当前的对象数目。

console.log(setOfObjects.size);

遍历Set

之前提到过,Set 可以通过常规的 for…of 循环来遍历。除此之外,对于Set,还有一些其它的迭代或者循环方式。如下所示: (* 表明方法返回迭代器)

*entries(): 返回一个包含key-value组合对象的迭代器。由于键值(key值)和数值(value值)在Set中是一样的,每个入口都是一个不断重复关联数值的数组。

for(let item of setOfObjects.entries()){
    console.log(item);
}

*values(): 返回遍历Set中数值(value值)的迭代器。

for(let item of setOfObjects.values()){
    console.log(item);
}

*keys():返回遍历Set中键值(Key值)的迭代器.  由于键值(key值)和数值(value值)在Set中是一样的,所以keys方法和values方法返回一样的结果

for(let item of setOfObjects.keys()){
    console.log(item.);
}

forEach(callback): 这是Set中遍历入口的另一种方法。Set中的每个入口都会调用回调函数

setOfObjects.forEach(item => console.log(item));

gones945
gones945
翻译于 2015/03/18 21:13
2

WeakSet

WeakSetSet 对应的弱引用版本。WeakSet 不会阻止插入其中的值被垃圾收集。它的工作方式和 Set 类似,但也有以下例外:

  • 只能包含对象。属于 Number、String、Boolean、null 和 undefined 的值都不能被添加进 WeakSet

  • 无法迭代或遍历 WeakSet 中包含的值,也就是说,WeakSet 不支持像 values()entries()forEach() 那样的方法

  • WeakSet 支持以下一组操作:addhasdelete。这些方法工作起来和用 Set 时一样

之所以取名叫 WeakSet,是因为它们不会阻止存储在它们内部的值被垃圾回收。

由于 WeakSet 天生存在上述限制,只有少数情况下会用到它。

霍啸林
霍啸林
翻译于 2015/03/18 13:41
1

Map和WeakMap

Map

Map是键值对(key-value pair)对象;键(key)和值(value)可以是任意的JavaScript对象或值。键(key)在给定的Map中必须是唯一的。像Set一样,Map是可迭代的。

新的Map对象可以通过如下的 Map 构造函数来创建:

varmyDictionary =newMap(...arguments);

Map 构造函数参数是可选的。 如果传递参数,这些参数将会用来创建Map;否则,Map 对象将不会包含任何内容。

下面的代码段显示了如何使用对象集合来创建Map

varmyDictionary =newMap([["key1","value1"], ["key2","value2"]]);

由于字典是可迭代的,我们可以使用 for…of 循环遍历每个子项。

for(let dictionaryEntry of myDictionary){
    console.log(dictionaryEntry);
}

Map 提供了一系列方法与之交互。让我们来看一看。

gones945
gones945
翻译于 2015/03/19 22:11
1

增加项目

新的项目可以通过set()方法加入到Map之中。 这个方法会检查传递到Map的键是否已经存在,如果键不存在,则将其添加到Map之中;否则就放弃。

下面的代码段增加了更多的项目到之前创建的Map之中:

myDictionary.set("key3","value4");
myDictionary.set("key2","value5");
 
varobj = {id:"1"};
 
myDictionary.set(obj, 1000);
myDictionary.set(obj, 1900);

key2 作为键,同时以obj 作为键,尝试插入myDictionary的时候,由于它们在myDictionary中已经存在,所以会被丢弃。

键通过引用校验,而不是值。 所以,下面的代码段会增加一个项目到myDictionary之中。

myDictionary.set({id:"1"}, 826);
gones945
gones945
翻译于 2015/03/19 22:25
1

通过 key 获取 value

如果 key 是已知的,那么可以使用 get() 方法从一个 Map 中提取 value。如果无法在 Map 中找到 key,那么方法会返回 undefined。

检查一个 key 是否存在

我们可以用 has() 方法检查一个 key 是否已经添加到 Map 中。和 Set 的情况类似,has() 方法按引用检查 key 的匹配项。

console.log(myDictionary.has("key2"));      // true
console.log(myDictionary.has(obj));         // true
console.log(myDictionary.has({id: "1"}));   // false

通过 key 得到 value

如果 key 是已知的,那么可以使用 get 方法从一个 Map 中提取 value。如果无法在 Map 中找到 key,则方法将返回 undefined。

console.log(myDictionary.get("key2"));      // value2
console.log(myDictionary.get("key2ii"));    // undefined
霍啸林
霍啸林
翻译于 2015/03/17 21:04
1

移除对象

Map 中的对象可以通过 delete  方法一个个的移除,也可以通过 clear 方法一下子全部移除。delete 方法接收 key 值,如果找到这个 key 值所对应的条目并成功删除,返回 'true',否则返回 'false'。

下面是调用deleteclear 方法的一些例子:

console.log(myDictionary.delete({prop: 2000})); //false
console.log(myDictionary.delete(obj));          //true
console.log(myDictionary.delete("key1"));       //true
 
myDictionary.clear();


Map 的大小

Map 对象的 size 属性保存了 Map 中条目的个数。

console.log(myDictionary.size);


遍历 Map

在前面曾提到过,Maps 可以通过常规的 for...of 语句进行遍历。另外,还有一些方法可以遍历或循环 Maps 中 key 或 value 的值。下面是这些方法的示例(*表示返回值为迭代器) 

*entries(): 返回一个包含 key-value pair 对象的迭代器。迭代器的每个条目是一个长度为 2 的数组,其中第一个值为 key,第二个值为 value。

for(let item of myDictionary.entries()){
    console.log(item);
}

*values(): 返回一个包含 Map 中所有 value 的迭代器

for(let item of myDictionary.values()){
    console.log(item);
}

*keys():返回一个包含 Map 中所有 key 的迭代器

for(let item of myDictionary.keys()){
    console.log(item);
}

forEach(callback): 另外一种循环 Map 中 key 值的方法。对于每一个 key,都会调用一次 Callback 函数。

myDictionary.forEach(item => console.log(item));

鱼十三
鱼十三
翻译于 2015/03/20 14:25
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(16)

knightuniverse
knightuniverse

引用来自“巫云”的评论

目前5都没用被各家的js引擎完全实现吧

引用来自“knightuniverse”的评论

好像确实还有有一些API没有实现...但是ES6 你可以跑在nodejs等之上啊。

引用来自“QuenTine”的评论

es5-shim和es6-shim
这个我也知道,我说的是原生支持的。
QuenTine
QuenTine

引用来自“with_you”的评论

差评,这的这么对象化直接coffescripy,typesicrpt算了
新特性不只是旧特性的语法糖,脚本引擎肯定会根据新特性优化的。 虽然es5能凑合实现es6的特性,但不能完全实现。比如说实现一下es6的在子类构造函数里调用父类构造函数。
QuenTine
QuenTine

引用来自“巫云”的评论

目前5都没用被各家的js引擎完全实现吧

引用来自“knightuniverse”的评论

好像确实还有有一些API没有实现...但是ES6 你可以跑在nodejs等之上啊。
es5-shim和es6-shim
c
ccto
js赶快死吧
slver888
slver888
是要准备跪舔python么?
l
liwenhui

引用来自“with_you”的评论

差评,这的这么对象化直接coffescripy,typesicrpt算了
+1023
OSC首席键客
OSC首席键客
http://www.360us.net/books/es6tutorial.html
介绍ES6的书籍!
chenwenli
chenwenli

引用来自“巫云”的评论

目前5都没用被各家的js引擎完全实现吧

引用来自“knightuniverse”的评论

好像确实还有有一些API没有实现...但是ES6 你可以跑在nodejs等之上啊。
iojs比nodejs更激进
卖爷爷的老红薯
卖爷爷的老红薯
至少十年不用学!
从今以后
从今以后
awesome!
返回顶部
顶部