如何将一个普通的对象转换成一个ES6映射?

出于某种原因,我无法在MDN文档中find这个简单的东西(也许我只是想念它)。

我期待这个工作:

const map = new Map({foo: 'bar'}); map.get('foo'); // 'bar' 

…但第一行引发TypeError: (var)[Symbol.iterator] is not a function

我如何从一个普通的对象做一个地图? 我真的必须首先将其转换为一组键值对的数组吗?

要初始化Map ,可以使用任何将键/值对作为数组返回的迭代器,例如数组数组:

 const map = new Map([ ['foo', 'bar'] ]); 

没有从对象到映射的内置转换,但可以通过Object.keys轻松完成:

 const map = new Map(); let obj = {foo: 'bar'}; Object.keys(obj).forEach(key => { map.set(key, obj[key]); }); 

当然,你可以给自己一个工人的function来处理:

 function buildMap(obj) { let map = new Map(); Object.keys(obj).forEach(key => { map.set(key, obj[key]); }); return map; } 

然后

 const map = buildMap({foo: 'bar'}); 

或者这里还有更多的东西(这还是东西?)版本:

 function buildMap(obj) { return Object.keys(obj).reduce((map, key) => map.set(key, obj[key]), new Map()); } 

(是的, Map#set返回地图引用,有人会认为这是一个reduce

或者,我们真的可以在默默无闻的情况下超越:

 const buildMap = o => Object.keys(o).reduce((m, k) => m.set(k, o[k]), new Map()); 

不,我永远不会那样做。 🙂

是的, Map构造函数接受一组键 – 值对。

Object.entries有一个ES Stage4提议 ,它返回一个对象的键值数组:

 const map = new Map(Object.entries({foo: 'bar'})); map.get('foo'); // 'bar' 

它目前在Firefox 46 +和Edge 14+中实现(在Chrome中是一个标志)。

如果你不能select转录,请查看TJ Crowder的答案或者使用一个polyfill,比如georg推荐的那个:

 Object.entries = typeof Object.entries === 'function' ? Object.entries : obj => Object.keys(obj).map(k => [k, obj[k]]); 

更新19.09.2017:在ES2017

正如AnilRedshift在评论中提到的, Object.entries现在是ES2017最终规范(19.1.2.5)的一部分 。

我真的必须首先将其转换为一组键值对的数组吗?

不,键值对数组的迭代器就足够了。 您可以使用以下内容来避免创build中间数组:

 function* entries(obj) { for (let key in obj) yield [key, obj[key]]; } const map = new Map(entries({foo: 'bar'})); map.get('foo'); // 'bar' 
 const myMap = new Map( Object .keys(myObj) .map( key => [key, myObj[key]] ) ) 

或者,您可以使用lodash toPairs方法:

 const _ = require('lodash'); const map = new Map(_.toPairs({foo: 'bar'}));