diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/javascript/guide/keyed_collections | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/zh-cn/web/javascript/guide/keyed_collections')
-rw-r--r-- | files/zh-cn/web/javascript/guide/keyed_collections/index.html | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/files/zh-cn/web/javascript/guide/keyed_collections/index.html b/files/zh-cn/web/javascript/guide/keyed_collections/index.html new file mode 100644 index 0000000000..0c10c93c2a --- /dev/null +++ b/files/zh-cn/web/javascript/guide/keyed_collections/index.html @@ -0,0 +1,155 @@ +--- +title: 带键的集合 +slug: Web/JavaScript/Guide/Keyed_collections +tags: + - Guide + - JavaScript + - Map + - set + - 集合 +translation_of: Web/JavaScript/Guide/Keyed_collections +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</div> + +<p class="summary">这一章介绍由key值标记的数据容器;Map 和 Set 对象承载的数据元素可以按照插入时的顺序被迭代遍历。</p> + +<h2 id="映射">映射</h2> + +<h3 id="Map对象"><code>Map</code>对象</h3> + +<p>ECMAScript 2015 引入了一个新的数据结构来将一个值映射到另一个值。一个{{jsxref("Map")}}对象就是一个简单的键值对映射集合,可以按照数据插入时的顺序遍历所有的元素。</p> + +<p>下面的代码演示了使用<code>Map</code>进行的一些基本操作。请参考{{jsxref("Map")}}以获取更多的样例和完整的 API。你可以使用{{jsxref("Statements/for...of","for...of")}}循环来得到所有的<code>[key, value]</code>。</p> + +<pre class="brush: js">var sayings = new Map(); +sayings.set('dog', 'woof'); +sayings.set('cat', 'meow'); +sayings.set('elephant', 'toot'); +sayings.size; // 3 +sayings.get('fox'); // undefined +sayings.has('bird'); // false +sayings.delete('dog'); +sayings.has('dog'); // false + +for (var [key, value] of sayings) { + console.log(key + ' goes ' + value); +} +// "cat goes meow" +// "elephant goes toot" + +sayings.clear(); +sayings.size; // 0</pre> + +<h3 id="Object和Map的比较"><code><font face="Consolas, Liberation Mono, Courier, monospace">Object</font></code>和<code>Map</code>的比较</h3> + +<p>一般地,{{jsxref("Object", "objects", "", 1)}}会被用于将字符串类型映射到数值。<code>Object</code>允许设置键值对、根据键获取值、删除键、检测某个键是否存在。而<code>Map</code>具有更多的优势。</p> + +<ul> + <li><code>Object</code>的键均为<code>Strings</code>类型,在<code>Map</code>里键可以是任意类型。</li> + <li>必须手动计算<code>Object</code>的尺寸,但是可以很容易地获取使用<code>Map</code>的尺寸。</li> + <li><code>Map</code>的遍历遵循元素的插入顺序。</li> + <li><code>Object</code>有原型,所以映射中有一些缺省的键。<font face="Open Sans, Arial, sans-serif">(</font>可以用 <code>map = Object.create(null) 回避</code>)。</li> +</ul> + +<p>这三条提示可以帮你决定用<code>Map</code>还是<code>Object</code>:</p> + +<ul> + <li>如果键在运行时才能知道,或者所有的键类型相同,所有的值类型相同,那就使用<code>Map</code>。</li> + <li>如果需要将原始值存储为键,则使用<code>Map</code>,因为<code>Object</code>将每个键视为字符串,不管它是一个数字值、布尔值还是任何其他原始值。</li> + <li>如果需要对个别元素进行操作,使用<code>Object</code>。</li> +</ul> + +<h3 id="WeakMap对象"><code>WeakMap</code>对象</h3> + +<p>{{jsxref("WeakMap")}}对象也是键值对的集合。它的<strong>键必须是对象类型</strong>,值可以是任意类型。它的键被弱保持,也就是说,当其键所指对象没有其他地方引用的时候,它会被GC回收掉。<code>WeakMap</code>提供的接口与<code>Map</code>相同。</p> + +<p>与<code>Map</code>对象不同的是,<code>WeakMap</code>的键是不可枚举的。不提供列出其键的方法。列表是否存在取决于垃圾回收器的状态,是不可预知的。</p> + +<p>可以在"Why <em>Weak</em>Map?"{{jsxref("WeakMap")}}查看更多信息和示例。</p> + +<p><code>WeakMap</code>对象的一个用例是存储一个对象的私有数据或隐藏实施细节。Nick Fitzgerald 的博文<a href="http://fitzgeraldnick.com/weblog/53/">"Hiding Implementation Details with ECMAScript 6 WeakMaps"</a>提供了一个例子。对象内部的私有数据和方法被存储在<code>WeakMap</code>类型的<code>privates</code>变量中。所有暴露出的原型和情况都是公开的,而其他内容都是外界不可访问的,因为模块并未导出<code>privates</code>对象。</p> + +<pre class="brush: js">const privates = new WeakMap(); + +function Public() { + const me = { + // Private data goes here + }; + privates.set(this, me); +} + +Public.prototype.method = function () { + const me = privates.get(this); + // Do stuff with private data in `me`... +}; + +module.exports = Public; +</pre> + +<h2 id="集合">集合</h2> + +<h3 id="Set对象"><code>Set</code>对象</h3> + +<p>{{jsxref("Set")}}对象是一组值的集合,这些值是不重复的,可以按照添加顺序来遍历。</p> + +<p>这里演示了<code>Set</code>的基本操作,更多示例和完整API可以参考{{jsxref("Set")}}。</p> + +<pre class="brush: js">var mySet = new Set(); +mySet.add(1); +mySet.add("some text"); +mySet.add("foo"); + +mySet.has(1); // true +mySet.delete("foo"); +mySet.size; // 2 + +for (let item of mySet) console.log(item); +// 1 +// "some text" +</pre> + +<h3 id="数组和集合的转换">数组和集合的转换</h3> + +<p>可以使用{{jsxref("Array.from")}}或<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_operator">展开操作符</a>来完成集合到数组的转换。同样,<code>Set</code>的构造器接受数组作为参数,可以完成从<code>Array</code>到<code>Set</code>的转换。需要重申的是,<code>Set</code>对象中的值不重复,所以数组转换为集合时,所有重复值将会被删除。</p> + +<pre class="brush: js">Array.from(mySet); +[...mySet2]; + +mySet2 = new Set([1,2,3,4]); +</pre> + +<h3 id="Array和Set的对比"><code>Array</code>和<code>Set</code>的对比</h3> + +<p>一般情况下,在JavaScript中使用数组来存储一组元素,而新的集合对象有这些优势:</p> + +<ul> + <li>数组中用于判断元素是否存在的{{jsxref("Array.indexOf", "indexOf")}} 函数效率低下。</li> + <li><code>Set</code>对象允许根据值删除元素,而数组中必须使用基于下标的 splice 方法。</li> + <li>数组的<code>indexOf</code>方法无法找到{{jsxref("NaN")}}值。</li> + <li><code>Set</code>对象存储不重复的值,所以不需要手动处理包含重复值的情况。</li> +</ul> + +<h3 id="WeakSet对象"><code>WeakSet</code>对象</h3> + +<p>{{jsxref("WeakSet")}}对象是一组对象的集合。<code>WeakSet</code>中的对象不重复且不可枚举<font face="Consolas, Liberation Mono, Courier, monospace">。</font></p> + +<p>与{{jsxref("Set")}}对象的主要区别有:</p> + +<ul> + <li><code>WeakSets</code>中的值必须是对象类型,不可以是别的类型</li> + <li><code>WeakSet</code>的“<em>weak</em>”指的是,对集合中的对象,如果不存在其他引用,那么该对象将可被垃圾回收。于是不存在一个当前可用对象组成的列表,所以<code>WeakSets</code>不可枚举</li> +</ul> + +<p><code>WeakSet</code>的用例很有限,比如使用DOM元素作为键来追踪它们而不必担心内存泄漏。</p> + +<h2 id="Map的键和Set的值的等值判断"><code>Map</code>的键和<code>Set</code>的值的等值判断</h2> + +<p><code>Map</code>的键和<code>Set</code>的值的等值判断都基于<a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero">same-value-zero algorithm</a>:</p> + +<ul> + <li>判断使用与<code>===</code>相似的规则。</li> + <li><code>-0</code>和<code>+0</code>相等。</li> + <li>{{jsxref("NaN")}}与自身相等(与<code>===</code>有所不同)。</li> +</ul> + +<p>{{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</p> |