ES6新特性:Javascript中的Map和WeakMap对象
Map对象
Map对象是一种有对应 键/值 对的对象, JS的Object也是 键/值 对的对象 ;
ES6中Map相对于Object对象有几个区别:
1:Object对象有原型, 也就是说他有默认的key值在对象上面, 除非我们使用Object.create(null)创建一个没有原型的对象;
2:在Object对象中, 只能把String和Symbol作为key值, 但是在Map中,key值可以是任何基本类型(String, Number, Boolean, undefined, NaN....),或者对象(Map, Set, Object, Function , Symbol , null....);
3:通过Map中的size属性, 可以很方便地获取到Map长度, 要获取Object的长度, 你只能用别的方法了;
Map实例对象的key值可以为一个数组或者一个对象,或者一个函数,比较随意 ,而且Map对象实例中数据的排序是根据用户push的顺序进行排序的, 而Object实例中key,value的顺序就是有些规律了, (他们会先排数字开头的key值,然后才是字符串开头的key值);
Map实例的属性
map.size这个属性和数组的length是一个意思,表示当前实例的长度;
Map实例的方法
clear()方法, 删除所有的键/值对;
delete(key), 删除指定的键/值对;
entries()返回一个迭代器, 迭代器按照对象的插入顺序返回[key, value];
forEach(callback , context) 循环执行函数并把键/值对作为参数; context为执行函数的上下文this;
get(key) 返回Map对象key相对应的value值;
has(key) 返回布尔值, 其实就是返回Map对象是否有指定的key;
keys() 返回一个迭代器,迭代器按照插入的顺序返回每一个key元素;
set(key, value) 给Map对象设置key/value 键/值对, 返回这个Map对象(相对于Javascript的Set,Set对象添加元素的方法叫做add,而Map对象添加元素的方法为set;
[@@iterator] 和entrieds()方法一样, 返回一个迭代器, 迭代器按照对象的插入顺序返回[key, value];
自己模拟一个Map构造器:
既然知道了Map对象的方法和属性, 我们也可以自己模拟一个Map构造器, 需要生成器的支持, 所以要在ES5中使用还需要生成器的补丁(模拟Set构造器) :
<html>
<head>
<meta charMap="utf-8">
</head>
<body>
<script>
"use strict";
class Map {
/**
* @param [[key, value], [k, val]];
* @return void;
*/
static refresh (arg) {
for(let [key,value] of arg) {
//判断是否重复了;
let index = Map.has.call(this, key);
if(index===false) {
this._keys.push(key);
this._values.push(value);
}else{
//如果有重复的值,那么我们执行覆盖;
this._keys[index] = key;
this._values[index] = value;
}
};
this.size = this._keys.length;
}
/**
* @desc return false || Number;
* */
static has (key) {
var index = this._keys.indexOf(key);
if(index === -) {
return false;
}else{
return index;
};
}
constructor(arg) {
this._keys = [];
this._values = [];
Map.refresh.call(this, arg);
}
set (key, value) {
Map.refresh.call(this, [[key,value]]);
return this;
}
clear () {
this._keys = [];
this._values = [];
return this;
}
delete (key) {
var index = Map.has.call(this, key);
if(index!==false) {
this._keys.splice(index,);
this._values.splice(index,);
};
return this;
}
entries () {
return this[Symbol.iterator]();
}
has (key) {
return Map.has.call(this, key) === false ? false : true;
}
*keys() {
for(let k of this._keys) {
yield k;
}
}
*values () {
for(let v of this._values) {
yield v;
}
}
//直接使用数组的forEach方便啊;
forEach (fn, context) {
return this;
}
//必须支持生成器的写法;
*[Symbol.iterator] (){
for(var i=; i<this._keys.length; i++) {
yield [this._keys[i], this._values[i]];
}
}
};
var map = new Map([["key","value"]]);
map.set("heeh","dada");
console.log(map.has("key")); //输出:true;
map.delete("key");
console.log(map.has("key")); //输出:false;
map.set("key","value");
var keys = map.keys();
var values = map.values();
console.log(keys.next());
console.log(keys.next());
console.log(values.next());
console.log(values.next());
var entries = map.entries();
console.log(entries);
</script>
</body>
</html>
Map的使用Demo:
var myMap = new Map(); var keyString = "a string",
keyObj = {},
keyFunc = function () {}; // 我们给myMap设置值
myMap.set(keyString, "字符串'");
myMap.set(keyObj, "对象");
myMap.set(keyFunc, "函数"); myMap.size; // 输出长度: 3 // 获取值
console.log(myMap.get(keyString)); // 输出:字符串
console.log(myMap.get(keyObj)); // 输出:对象
console.log(myMap.get(keyFunc)); // 输出:函数 console.log(myMap.get("a string")); // 输出:字符串 console.log(myMap.get({})); // 输出:undefined
console.log(myMap.get(function() {})) // 输出:undefined
我们也可以把NaN,undefined, 对象,数组,函数等这些作为一个Map对象的key值 :
"use strict";
let map = new Map();
map.set(undefined, "");
map.set(NaN, {});
console.log(map); //输出:Map { undefined => '0', NaN => {} }
循环Map的方法
使用Map实例的forEach方法;
"use strict";
let map = new Map();
map.set(undefined, "");
map.set(NaN, {});
map.forEach(function(value ,key ,map) {
console.log(key,value, map);
});
使用for...of循环:
"use strict";
let map = new Map();
map.set(undefined, "");
map.set(NaN, {});
for(let [key, value] of map) {
console.log(key, value);
}
for(let arr of map) {
console.log(arr);
}
WeakMap
WeakMap是弱引用的Map对象, 如果对象在js执行环境中不存在引用的话,相对应的WeakMap对象内的该对象也会被js执行环境回收;
WeakMap对象的属性:无
WeakMap对象的方法:
delete(key) : 删除指定的键/值对;
get(key) :返回Map对象key相对应的value值;
has(key) :返回布尔值, 其实就是返回Map对象是否有指定的key;
set(key):给Map对象设置key/value 键/值对, 返回这个Map对象;
WeakMap相对于Map少了很多的方法, 我们也可以自己再来实现这些方法,比如我们再实现一个Map实例的clear方法:
class ClearableWeakMap {
constructor(init) {
this._wm = new WeakMap(init)
}
clear() {
this._wm = new WeakMap()
}
delete(k) {
return this._wm.delete(k)
}
get(k) {
return this._wm.get(k)
}
has(k) {
return this._wm.has(k)
}
set(k, v) {
this._wm.set(k, v)
return this
}
}
参考:
MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map;
ruanyifeng:http://es6.ruanyifeng.com/#docs/set-map
作者: NONO
出处:http://www.cnblogs.com/diligenceday/
QQ:287101329
微信:18101055830
ES6新特性:Javascript中的Map和WeakMap对象的更多相关文章
- javascript ES6 新特性之 扩展运算符 三个点 ...
对于 ES6 新特性中的 ... 可以简单的理解为下面一句话就可以了: 对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中. 作用类似于 Object.assign() ...
- ES6新特性概览
本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代号harmony( ...
- Atitit js版本es5 es6新特性
Atitit js版本es5 es6新特性 Es5( es5 其实就是adobe action script的标准化)1 es6新特性1 Es5( es5 其实就是adobe action scrip ...
- 你不知道的JavaScript--Item24 ES6新特性概览
ES6新特性概览 本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代 ...
- 前端入门21-JavaScript的ES6新特性
声明 本篇内容全部摘自阮一峰的:ECMAScript 6 入门 阮一峰的这本书,我个人觉得写得挺好的,不管是描述方面,还是例子,都讲得挺通俗易懂,每个新特性基本都还会跟 ES5 旧标准做比较,说明为什 ...
- 34.js----JS 开发者必须知道的十个 ES6 新特性
JS 开发者必须知道的十个 ES6 新特性 这是为忙碌的开发者准备的ES6中最棒的十个特性(无特定顺序): 默认参数 模版表达式 多行字符串 拆包表达式 改进的对象表达式 箭头函数 =&> ...
- ES6新特性概览1
本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代号harmony( ...
- ES6新特性:Proxy代理器
ES6新特性:Proxy: 要使用的话, 直接在浏览器中执行即可, node和babel目前还没有Proxy的polyfill;,要使用的话,直接在浏览器中运行就好了, 浏览器的兼容性为:chrome ...
- ES6新特性简介
ES6新特性简介 环境安装 npm install -g babel npm install -g babel-node //提供基于node的REPL环境 //创建 .babelrc 文件 {&qu ...
随机推荐
- NOIP2011pj表达式的值[树形DP 笛卡尔树 | 栈 表达式解析]
题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × ...
- NOIP1999邮票面值设计[搜索|DP]
题目描述 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1-MAX之间的每一个邮资值都能得到 ...
- VS Code
VS Code VS Code(Visual Studio Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器.几乎完美的编辑器. 官网:https://code.visualstudi ...
- .Net程序员学习Linux最简单的方法
有很多关于Linux的书籍,博客.大多数都会比较“粗暴“的将一大堆的命令塞给读者,从而使很多.NET程序员望而却步.未入其门就路过了. 所以我设想用一种更为平滑的学习方式, 就是在学习命令时,先用纯语 ...
- PAT 1008. 数组元素循环右移问题 (20)
一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1--AN-1)变换为(AN-M -- AN-1 A0 ...
- HRV基础
Source: Mostly from wiki. Heart rate variability (HRV,心率变异性) is the physiological phenomenon of vari ...
- 快速排名 让人疯狂的黑帽seo技术
对于黑帽seo大家或许并不陌生,黑帽seo和白帽seo恰恰相反,是作弊手段.有白帽seo的时候,就有了黑帽seo一直到现在.但隔行如隔山这句话这句话一点都没错,再没接触黑帽seo技术之前我根本不知道黑 ...
- 数据库 SQL语法一
建立表语句 CREATE TABLE TABLENAME(COL_NAME1 TYPE,COL_NAME2 TYPE,......); 常用TYPE说明 INT 正数 CHAR(LENGTH) 定长字 ...
- 如果动态设置json对象的key
项目中要求动态设置json的key属性,如果按照一般的json设置方法是不行的.假如你把一个key设置为一个变量的话,那么最后js解析出来的就是key为这个变量名而不是这个变量的值. 解决:通过使用 ...
- MyBatis拦截器原理探究
MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...