码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript Map对象

时间:2020-07-30 01:30:11      阅读:503      评论:0      收藏:0      [点我收藏+]

标签:ror   int   es5   size   基本类型   返回   顺序   log   body   

JavaScript Map对象

Map

  Map是一组键值对的结构,用于解决以往不能用对象做为键的问题

 

  具有极快的查找速度

  函数、对象、基本类型都可以作为键或值

 

  其实Map和对象非常相似,但是对象的键只能是String类型或Symbol类型,Map在这方面就显得自由开放,以下是Map与对象的对比。

 

MapObject 
意外的键 Map 默认情况不包含任何键。只包含显式插入的键。 一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。注意: 虽然 ES5 开始可以用 Object.create(null) 来创建一个没有原型的对象,但是这种用法不太常见。
键的类型 一个 Map的键可以是任意值,包括函数、对象或任意基本类型。 一个Object 的键必须是一个 String 或是Symbol
键的顺序 Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。 一个 Object 的键是无序的注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。
Size Map 的键值对个数可以轻易地通过size 属性获取 Object 的键值对个数只能手动计算
迭代 Mapiterable 的,所以可以直接被迭代。 迭代一个Object需要以某种方式获取它的键然后才能迭代。
性能 在频繁增删键值对的场景下表现更好。 在频繁添加和删除键值对的场景下未作出优化。

 

声明定义


  使用Map()加上数组嵌套即可声明出一个Map容器。

<script>

        "use strict";

        let map = new Map([["k1", "v1"], ["k2", "v2"], ["k3", "v3"]]); 

        console.log(map instanceof Map);  // true

        console.log(map);  // Map(3) {"k1" => "v1", "k2" => "v2", "k3" => "v3"}

</script>

 

  对于键是对象的Map, 键保存的是内存地址,值相同但内存地址不同的视为两个键。这个时候是不会引发值冲突的问题,如果是相同内存地址的对象则会引发值冲突。

<script>

        "use strict";

        let arr = ["云崖"];  // 一个arr设置为了两个不同的键,这会引发值冲突的问题。

        let map = new Map([[arr, "v1"], ["k2", "v2"], [arr, "v3"]]);

        console.log(map);  // Map(2) {Array(1) => "v3", "k2" => "v2"}

</script>

 

新增数据


  使用set()方法为Map容器新增一组键值对。

 

<script>
?
        "use strict";
?
        let map = new Map();
?
        map.set("k1","v1");
        
        map.set("k2","v2");
?
        console.log(map); // Map(2) {"k1" => "v1", "k2" => "v2"}
?
</script>

 

获取数量


  使用size属性获取当前map容器中键值对的数量。

 

<script>
?
        "use strict";
?
        let map = new Map();
?
        map.set("k1","v1");
?
        map.set("k2","v2");
?
        console.log(map.size); // 2
?
</script>

 

元素检测


  使用has()方法检测当前map容器中是否存在某个键,返回布尔值。

 

  注意:如果键是引用类型则必须要使用原本键对象的引用才行,单纯的形式相似是会返回false

 

<script>
?
        "use strict";
?
        let arr = new Array("云崖")
?
        let map = new Map();
?
        map.set(arr,"v1");
?
        map.set("k2","v2");
?
        console.log(map.has(arr)); // true 来自同一引用
        
        console.log(map.has(["云崖"])); // false 不来自同一引用,这里的数组是新开辟的内存空间
?
</script>

 

获取元素


  使用get()方法获取map容器中的一组键值对。

 

<script>
?
        "use strict";
?
        let arr = new Array("云崖")
?
        let map = new Map();
?
        map.set(arr,"v1");
?
        map.set("k2","v2");
?
        console.log(map.get(arr)); // v1 
?
        console.log(map.get(["云崖"])); // undefined
?
</script>

 

删除元素


  使用delete()方法删除map容器中的一组键值对。

  返回布尔值,true代表删除成功,false代表删除失败。

 

<script>
?
        "use strict";
?
        let arr = new Array("云崖")
?
        let map = new Map();
?
        map.set(arr,"v1");
?
        map.set("k2","v2");
?
        console.log(map.delete(arr)); // true
?
</script>

 

清空容器


  使用clear()方法可以使map容器清空。

 

<script>
?
        "use strict";
?
        let arr = new Array("云崖")
?
        let map = new Map();
?
        map.set(arr,"v1");
?
        map.set("k2","v2");
?
        map.clear()
?
        console.log(map); // Map(0) {}
?
</script>

 

数组转换


  可使用...语法或者Array.from()Map转换为Array

 

技术图片

 

 

遍历操作

迭代器创建


  使用 keys()/values()/entries() 都可以返回可遍历的迭代对象。

 

<script>
?
        "use strict";
?
        let map = new Map([["k1","v1"],["k2","v2"],["k3","v3"]]);
?
        console.log(map.keys());  // 拿到所有键
?
        console.log(map.values());  // 拿到所有值
?
        console.log(map.entries());  // 拿到所有键值对
?
</script>

 

技术图片

 

forEach


  使用forEach遍历操作。

 

<script>
?
        "use strict";
?
        let map = new Map([["k1", "v1"], ["k2", "v2"], ["k3", "v3"]]);
?
        map.forEach(function (key, value) {
                console.log(key,value);
        });
?
</script>

 

技术图片

 

for/of


  使用for/of遍历操作,直播遍历map容器等同于使用遍历entries() 函数

 

<script>
?
        "use strict";
?
        let map = new Map([["k1", "v1"], ["k2", "v2"], ["k3", "v3"]]);
?
        for (let [key, value] of map) {
                console.log(key, value);
        }
?
</script>

 

技术图片

 

 

WeakMap

  WeakMap对象是一组键/值对的集

 

  • 键名必须是对象

  • WeakMap对键名是弱引用的,键值是正常引用

  • 垃圾回收不考虑WeakMap的键名,不会改变引用计数器,键在其他地方不被引用时即删除

  • 因为WeakMap 是弱引用,由于其他地方操作成员可能会不存在,所以不可以进行forEach( )遍历等操作

  • 也是因为弱引用,WeakMap结构没有keys()values()entries()等方法和 size属性

  • 当键的外部引用删除时,希望自动删除数据时使用 WeakMap

 

声明定义


  WeakMap中的键值只能是容器类型的对象,即引用类型,不能是值类型。

<script>
?
        "use strict";
?
        let array = [1,2,3];
?
        let dict = {"k1":"v1","k2":"v2"};
?
        let map = new WeakMap([[array,"k1"],[dict,"k2"]]);
?
        console.log(map); // WeakMap {Array(3) => "k1", {…} => "k2"}
?
</script>

 

  值类型作为键会抛出异常。

<script>
?
        "use strict";
?
        let array = [1,2,3];
?
        let dict = {"k1":"v1","k2":"v2"};
?
        let map = new WeakMap([[array,"k1"],[dict,"k2"],[3,"k3"]]);
?
        console.log(map); // Uncaught TypeError: Invalid value used as weak map key
?
</script>

 

操作方法


 

方法说明
add() 添加一组键值对,键必须是引用类型的对象。
delete() 删除一组键值对
has() 判断是否存在一个引用类型对象的键值对

 

垃圾回收


  对于标记清除法来说,存在于WeakMap中的对象键并不会为其增加引用计数,因此也被称之为弱引用。

  当WeakMap中对象键的外部引用计数为0后,垃圾回收机制将清理 WeakMap容器中的该对象键,这会使得WeakMap容器中该对象键将被移除。

 

<script>
?
        "use strict";
?
        let array = [1, 2, 3];
?
        let dict = { "k1": "v1", "k2": "v2" };
?
        let map = new WeakMap([[array, "v1"],[dict,"v2"]]);
?
        console.log(map);  // array还在里面
?
        array = null;  // 清理,引用计数为0
?
        setInterval(() => {
?
                console.log(map);  // array 不在了
?
        }, 3000);
?
</script>

 

技术图片

 

作用详解


  根据WeakMap这个特性,我们可以用它来保存一下经常存取的数据。

  当对象被删除后,我们不用管WeakMap容器中是否含存有该数据。

 

JavaScript Map对象

标签:ror   int   es5   size   基本类型   返回   顺序   log   body   

原文地址:https://www.cnblogs.com/Yunya-Cnblogs/p/13401421.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!