• 重学JavaScript


    作者:狐狸家的鱼

    GitHub:surRimn

    整理自MDN文档

    带键的集合

    映射

    Map对象

    一个Map对象在迭代时会根据对象中元素的插入顺序来进行 — 一个 for...of 循环在每次迭代后会返回一个形式为[key,value]的数组。

    1、语法
    new Map([iterable])

    iterable可以是一个数组或者其他iterable对象,其元素或为键值对,或为两个元素的数值。每个键值对都添加到新的Mapnull会被当作undefined

    2、属性
    • Map.length:属性length的值为0
    • get Map[@@species]:构造函数用于创建派生对象
    • Map.prototype:表示Map构造器的原型,允许添加属性从而用于所有的Map对象
    3、键的相等

    键的比较是基于 "SameValueZero" 算法:NaN 是与 NaN 相等的(虽然 NaN !== NaN),剩下所有其它的值是根据 === 运算符的结果判断是否相等。+0 和-0是相同的值。

    4、Object 和 Map的比较

    Object会被用于将字符串类型映射到数值。Object允许设置键值对、根据键获取值、删除键、检测某个键是否存在

    • Object的键只能是字符串或者 Symbols,在Map里键可以是任意类型,包括函数、对象、基本类型;

    • 必须手动计算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);//3
    ​
    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);//0
    //打印台信息:
    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是不同的值。NaNundefined都可以被存储在Set 中, NaN之间被视为相同的值(尽管 NaN !== NaN

    3、属性
    • Set.lengthlength属性的值为0

    • get Set[@@species]:构造函数用来创建派生对象

    • Set.prototype:表示Set构造器的原型,允许向所有Set对象添加新的属性

    4、Set实例
    (1)属性
    • Set.prototype.constructor:返回实例的构造函数,默认是Set

    • Set.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的构造器接受数组作为参数,可以完成从ArraySet的转换。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对象存储不重复的值,所以不需要手动处理包含重复值的情况

    •  

     

  • 相关阅读:
    BGP综合部署
    网络综合部署
    部署LNMP架构
    编译安装Nginx网站服务及优化
    Apache网页优化
    在windows上安装jupyter,配置单机版pyspark
    剑指offer54-字符流中第一个不重复的字符
    在centos001上安装jupyter,配置单机版pyspark
    剑指offer53-表示数值的字符串
    剑指offer50-数组中重复的数字
  • 原文地址:https://www.cnblogs.com/suRimn/p/10861689.html
Copyright © 2020-2023  润新知