重学JavaScript - 映射与集合
作者:狐狸家的鱼
GitHub:surRimn
整理自MDN文档
带键的集合
映射
Map对象
一个Map对象在迭代时会根据对象中元素的插入顺序来进行 — 一个 for...of 循环在每次迭代后会返回一个形式为[key,value]的数组。
1、语法
new Map([iterable])
iterable可以是一个数组或者其他iterable对象,其元素或为键值对,或为两个元素的数值。每个键值对都添加到新的Map。null会被当作undefined。
2、属性
Map.length:属性length的值为0get Map[@@species]:构造函数用于创建派生对象Map.prototype:表示Map构造器的原型,允许添加属性从而用于所有的Map对象
3、键的相等
键的比较是基于 "SameValueZero" 算法:NaN 是与 NaN 相等的(虽然 NaN !== NaN),剩下所有其它的值是根据 === 运算符的结果判断是否相等。+0 和-0是相同的值。
4、Object 和 Map的比较
Object会被用于将字符串类型映射到数值。Object允许设置键值对、根据键获取值、删除键、检测某个键是否存在
必须手动计算
Object的尺寸,但是可以使用.size获取使用Map的尺寸Map的遍历遵循元素的插入顺序Map可直接进行迭代,而Object的迭代需要先获取它的键数组,然后再进行迭代Object有原型,所以映射中有一些缺省的键。(可以用map = Object.create(null) 回避)Map在涉及频繁增删键值对的场景下会有性能优势
这三条提示可以帮你决定用Map还是Object:
如果键在运行时才能知道,或者所有的键类型相同,所有的值类型相同,那就使用
Map如果需要将原始值存储为键,则使用
Map,因为Object将每个键视为字符串,不管它是一个数字值、布尔值还是任何其他原始值如果需要对个别元素进行操作,使用
Object
5、Map实例
所有的 Map 对象实例都会继承 Map.prototype
(1)属性
Map.prototype.constructor:返回一个函数,它创建了实例的原型,默认是Map函数Map.prototype.size:返回Map对象的键/值对的数量
(2)方法
| 方法 | 功能 |
|---|---|
Map.prototype.clear() |
移除Map对象的所有键/值对 |
Map.prototype.delete(key) |
如果 Map 对象中存在该元素,则移除它并返回 true;否则如果该元素不存在则返回 false |
Map.prototype.get(key) |
返回键对应的值,如果不存在,则返回undefined |
Map.prototype.has(key) |
返回一个布尔值,表示Map实例是否包含键对应的值 |
Map.prototype.set(key) |
设置Map对象中键的值。返回该Map对象 |
Map.prototype.keys() |
返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的键 |
Map.rpototype.values() |
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的值 |
Map.prototype.entries() |
返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value]**数组** |
Map.prototype.forEach(callbackFn[, thisArg]) |
按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。如果为forEach提供了thisArg,它将在每次回调中作为this值 |
Map.prototype[@@interator]() |
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的 [key, value]**数组** |
(3)示例
使用Map对象
let sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', "meow");
sayings.set('elephant', 'toot');
console.log(sayings.size);//
sayings.has('fox');
sayings.get('dog');
sayings.delete('dog');
sayings.has('dog');
for (let [key, value] of sayings) {
console.log(key + " goes " + value);
}
sayings.clear();
console.log(sayings.size);//
//打印台信息:
3
cat goes meow
elephant goes toot
0
将 NaN 作为 Map 的键
NaN 也可以作为Map对象的键。虽然 NaN 和任何值甚至和自己都不相等(NaN !== NaN 返回true)
//将NaN作为Map的键
let myMap = new Map();
myMap.set(NaN, "not a number");
console.log(myMap.get(NaN));//not a number
let otherNaN = Number("foo");
console.log(myMap.get(otherNaN));//not a number
迭代Map
//for..of迭代
for (let [key, value] of sayings) console.log(key + " goes " + value);
for (let key of sayings.keys()) console.log(key);
for (let value of sayings.values()) console.log(value);
for (let [key, value] of sayings.entries()) console.log(key + " goes " + value);
//打印台信息:
cat goes meow
elephant goes toot
cat
elephant
meow
toot
cat goes meow
elephant goes toot
//forEach()迭代
sayings.forEach((value, key) => {
console.log(key + " goes " + value);
}, sayings)
//打印台信息:
cat goes meow
elephant goes toot
Map与数组的关系
let arr = [
["key1", "value1"],
["key2", "value2"]
]
//使用Map构造函数将一个二维键值对数组转换成一个Map对象
let newMap = new Map(arr);
console.log(newMap.get("key1"));
//使用Array.from函数将一个Map对象转换成一个二维键值对数组
console.log(Array.from(newMap));
//在键或值的迭代器上使用Array.from,得到只含有键或值的数组
console.log(Array.from(newMap.keys()))
//打印台信息:
value1
[ [ 'key1', 'value1' ], [ 'key2', 'value2' ] ]
[ 'key1', 'key2' ]
复制或合并Maps
Map能像数组一样被复制
let original = new Map([
[1, 'one']
])
let clone = new Map(original);
console.log(clone.get(1));//one
console.log(original === clone);//false
PS:数据本身未被克隆。
Map对象间可以进行合并,但是会保持键的唯一性。
合并两个Map对象时,如果有重复的键值,则后面的会覆盖前面的。 展开运算符本质上是将Map对象转换成数组。
let first = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let second = new Map([
[1, 'uno'],
[2, 'dos']
]);
// 合并两个Map对象时,如果有重复的键值,则后面的会覆盖前面的。
// 展开运算符本质上是将Map对象转换成数组。
let merged = new Map([...first, ...second]);
console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
集合
Set对象
Set对象是一组不重复的值的集合,可以按照添加顺序来遍历。Set中的元素只会出现一次,即 Set 中的元素是唯一的。
1、语法
new Set([iterable])
如果传递一个可迭代对象,它的所有元素将不重复地被添加到新的 Set中。如果不指定此参数或其值为null,则新的 Set为空。
返回值为一个新的Set对象。
2、值的相等
对于 Set s, +0 (+0 严格相等于-0)和-0是不同的值。NaN和undefined都可以被存储在Set 中, NaN之间被视为相同的值(尽管 NaN !== NaN)
3、属性
Set.length:length属性的值为0get Set[@@species]:构造函数用来创建派生对象Set.prototype:表示Set构造器的原型,允许向所有Set对象添加新的属性
4、Set实例
(1)属性
Set.prototype.constructor:返回实例的构造函数,默认是SetSet.prototype.size:返回Set对象的键/值对的数量
(2)方法
| 方法 | 功能 |
|---|---|
Set.prototype.clear() |
移除Set对象内的所有元素 |
Set.prototype.delete(key) |
移除Set的中与这个值相等的元素,返回Set.prototype.has(value)在这个操作前会返回的值(即如果该元素存在,返回true,否则返回false)。``Set.prototype.has(value)在此后会返回false |
Set.prototype.add(key) |
在Set对象尾部添加一个元素。返回该``Set对象 |
Set.prototype.has(key) |
返回一个布尔值,表示该值在Set中存在与否 |
Set.prototype.keys() |
与values()方法相同,返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值 |
Set.rpototype.values() |
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值 |
Set.prototype.entries() |
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值的[value, value]数组。为了使这个方法和Map对象保持相似, 每个值的键和值相等 |
Set.prototype.forEach(callbackFn[, thisArg]) |
按照插入顺序,为Set对象中的每一个值调用一次callBackFn。如果提供了thisArg参数,回调中的this会是这个参数 |
Set.prototype[@@interator]() |
返回一个新的Iterator对象,它按插入顺序包含了Set对象中每个元素的 [key, value]**数组** |
(3)示例
使用Set对象
let set = new Set();
set.add(1);
set.add("some text");
set.add("foo");
console.log(set.size);
console.log(set.has(1));
set.delete("foo");
for (let item of set) {
console.log(item);
}
//打印台信息:
3
true
迭代Set
//迭代
for (let item of set) console.log(item);
for (let item of set.keys()) console.log(item);
for (let item of set.values()) console.log(item);
for (let [key, value] of set.entries()) console.log(key);
// 用forEach迭代
set.forEach(function (value) {
console.log(value);
});
//打印台信息:
1
some text
1
some text
1
some text
1
some text
1
some text
数组和集合的转换
使用Array.from或者展开操作符来完成集合到数组的转换。Set的构造器接受数组作为参数,可以完成从Array到Set的转换。Set`对象中的值不重复,所以数组转换为集合时,所有重复值将会被删除。
console.log(Array.from(set));//集合转换为数组
console.log([...set]); //用...(展开操作符)操作符将Set转换为Array
set = new Set([1, 2, 3, 4])//集合接收数组作为参数
console.log(set);
//打印台信息:
[ 1, 'some text' ]
[ 1, 'some text' ]
Set { 1, 2, 3, 4 }
String相关
const text = 'China';
set = new Set(text);
console.log(set);
console.log(set.size);
//打印台信息:
Set { 'C', 'h', 'i', 'n', 'a' }
5
数组去重
const num = [2, 3, 4, 4, 2, 4, 5];
console.log([...new Set(num)]);
//打印台信息:
[ 2, 3, 4, 5 ]
5、Array和Set的对比
在JavaScript中使用数组来存储一组元素,而新的集合对象有这些优势:
数组中用于判断元素是否存在的
indexOf函数效率低下Set对象允许根据值删除元素,而数组中必须使用基于下标的 splice 方法数组的
indexOf方法无法找到NaN值Set对象存储不重复的值,所以不需要手动处理包含重复值的情况
重学JavaScript - 映射与集合的更多相关文章
- 复习 Array,重学 JavaScript
1 数组与对象 在 JavaScript 中,一个对象的键只能有两种类型:string 和 symbol.下文只考虑键为字符串的情况. 1.1 创建对象 在创建对象时,若对象的键为数字,或者由 字母+ ...
- 重学JavaScript - 数组
作者:狐狸家的鱼 GitHub:surRimn 整理自MDN文档 数组 数组是一种类列表对象,长度和元素类型不固定. 描述 访问数组 JavaScript数组的索引是从0开始的,第一个元素的索引为0, ...
- 2.重学javascript 对象和数组
什么是对象,其实就是一种类型,即引用类型. 一.创建Object类型有两种. ①使用new运算符 <script type="text/javascript"> var ...
- 1.重学javascript (一)
一.script标签解析 <script>xxx</script>这组标签,是用于在html 页面中插入js的主要方法.它主要有以下 几个属性: 1.charset:可选.表示 ...
- 【重学Java】Set集合
Set集合 Set集合概述和特点[应用] 无序不可重复 没有索引,不能使用普通for循环遍历.可以使用迭代器或者增强foreach语句遍历 TreeSet集合 TreeSet集合概述和特点[应用] 无 ...
- 重学JavaScript之面向对象的程序设计(继承)
1. 继承 ES 中只支持实现继承,而且其实现继承主要依靠原型链来实现的. 2. 原型链 ES中 描述了 原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引 ...
- 重学JavaScript之匿名函数
1. 什么是匿名函数? 匿名函数就是没有名字的函数,有时候也称为< 拉姆达函数>.匿名函数是一种强大的令人难以置信的工具.如下: function a(a1, a2, a3) { // 函 ...
- 重学js之JavaScript 面向对象的程序设计(创建对象)
注意: 本文章为 <重学js之JavaScript高级程序设计>系列第五章[JavaScript引用类型]. 关于<重学js之JavaScript高级程序设计>是重新回顾js基 ...
- 《零基础学JavaScript(全彩版)》学习笔记
<零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...
随机推荐
- CF 49E Common ancestor
传送门 模拟赛T1就自闭了( 才不会说我是去刚T2了来着 感觉非常暴力的一个题? 出题人良心开大数据范围 n=100 还是原来的n^4*26算法我也是自闭了 不过貌似跑不到n^4? 真·大力出奇迹 一 ...
- 51nod 1831: 小C的游戏(Bash博弈 找规律)
题目链接 此类博弈不需要考虑sg函数,只需要确定必胜态和必败态,解题思路一般为打败先打表找规律,而后找规律给出统一的公式.打表方式:给定初始条件(此题中为ok[0]=ok[1]=0),然后从低到高枚举 ...
- 每天一个Linux命令:locate(19)
locate locate命令 让使用者可以很快速的搜寻档案系统内是否有指定的档案.其方法是先建立一个包括系统内所有档案名称及路径的数据库,之后当寻找时就只需查询这个数据库,而不必实际深入档案系统之中 ...
- 回炉Spring--Bean生命周期及AOP
Spring容器: 在基于Spring的应用中,你的应用对象生存于Spring容器(container)中,Spring容器负责创建对象,装配它们,配置它们并管理它们的整个生命周期,从生存到死亡.(在 ...
- Python3解leetcode Binary Tree PathsAdd Digits
问题描述: Given a non-negative integer num, repeatedly add all its digits until the result has only one ...
- flutter页面布局二
Stack 在flutter中,Stack表示堆的意思,可以用来实现页面的定位布局. Stack组件接收两个可选参数: alignment:配置所有子元素的显示位置 children:子组件 在 ...
- [CSP-S模拟测试]:party?(霍尔定理+最小割+树链剖分)
题目描述 $Treeland$国有$n$座城市,其中$1$号城市是首都,这些城市被一些单向高铁线路相连,对于城市$i\neq 1$,有一条线路从$i$到$p_i(p_i<i)$.每条线路都是一样 ...
- python中%代表什么意思?
http://zhidao.baidu.com/link?url=MQLeRPckNfavTJYvMQbVj_pdNn5SSadtFvfEk7nNCusPcPW4T1O45esIuttuBW3EnSB ...
- 使用Excel表格的记录单功能轻松处理工作表中数据的方法
使用Excel表格的记录单功能轻松处理工作表中数据的方法 记录单是将一条记录分别存储在同一行的几个单元格中,在同一列中分别存储所有记录的相似信息段.使用记录单功能可以轻松地对工作表中的数据进行查看.查 ...
- Pipenv管理项目环境--Django项目的一些最佳实践
virtualenv --- 使用不方便 提升效率,管理更便捷--- pipenv 新建环境:: pip3 install pipenv 在项目下,用pipenv安装 Djagno pipenv in ...