如何将 JavaScript ES6 映射对象显示到控制台?

Posted

技术标签:

【中文标题】如何将 JavaScript ES6 映射对象显示到控制台?【英文标题】:How can I Display a JavaScript ES6 Map Object to Console? 【发布时间】:2018-01-16 04:30:23 【问题描述】:

我正在使用repl.it/languages/javascript

在打印出来之前是否必须将其转换为对象?

我试过了

    const mapObject = new Map();
    
    mapObject.set(1, 'hello');
    
    console.log(JSON.stringify(mapObject));
    console.log(mapObject);

结果总是空对象。

当我使用时

console.log([...mapObject]);

它打印出一个数组格式。

【问题讨论】:

console.log(mapObject) 在最新的 Chrome 和 node7 中运行良好。你的平台是什么? @georg repl.it/languages/javascript 使用console.dir 代替.log,并且不进行字符串化。 @newguy:好吧,你给他们打个电话并要求解决这个问题怎么样? @georg 编辑后我的浏览器上仍然看到空对象。 【参考方案1】:

试试这个:

let mapObject = new Map();
mapObject.set("one", "file1");
mapObject.set("two", "file2");
mapObject.set("three", "file3");
console.log([...mapObject.entries()]);

输出将是:

[ [ 'one', 'file1' ], [ 'two', 'file2' ], [ 'three', 'file3' ] ]

这个解决方案的问题是,如果我们添加一个先前的字符串,输出会发生变化:

console.log("This is a map: " + [...mapObject.entries()]);

输出将是:

This is a map: one,file1,two,file2,three,file3

解决办法可以在here找到

【讨论】:

【参考方案2】:

我意识到这很可能是为浏览器控制台设计的,但这也发生在 Node.js 中。因此,您可以在 Node 中使用它来查看 Maps(或可能包含 Maps 的对象):

import * as util from "util";

const map: Map<string, string> = new Map();
map.set("test", "test");

const inspected: string = util.inspect(map);

console.log(inspected);

【讨论】:

【参考方案3】:

对于深度为 1 的简单映射,只需使用 Object.fromEntries([...map]) 将您的对象条目数组转换回控制台可记录对象:

const simpleObj = 
  a: [1, 2, 3],
  b: c: d: 42
;
const map = new Map(Object.entries(simpleObj));
console.log(Object.fromEntries([...map]));

但是,这对于复杂的嵌套地图会失败。为此,我们可以递归地将任何Maps 转换为对象,然后照常记录它。这是一个关于结合普通对象、Maps、数组和原语的复杂结构的概念验证。不要指望它会涵盖所有开箱即用的边缘情况,但请随时指出改进之处。

const convertMapToObjDeeply = o => 
  const recurseOnEntries = a => Object.fromEntries(
    a.map(([k, v]) => [k, convertMapToObjDeeply(v)])
  );
  
  if (o instanceof Map) 
    return recurseOnEntries([...o]);
  
  else if (Array.isArray(o)) 
    return o.map(convertMapToObjDeeply);
  
  else if (typeof o === "object" && o !== null) 
    return recurseOnEntries(Object.entries(o));
  
  
  return o;
;

const mkMap = o => new Map(Object.entries(o));

const map = mkMap(
  a: 42, 
  b: [1, 2, 3, mkMap(d: mkMap(ff: 55))],
  c: mkMap(
    e: [4, 5, 6, f: 5, x: y => y, mkMap(g: z => 1)]
  ),
  h: i: mkMap(j: 46, jj: new Map([[[1, 6], 2]])),
  k: mkMap(l: mkMap(m: [2, 5, x => x, 99]))
);

console.log(convertMapToObjDeeply(map));

【讨论】:

最好使用instanceof Map,而不是.constructor.name == 'Map'【参考方案4】:

您可以尝试一个更简单的解决方案。

 const mapObject = new Map();   
 mapObject.set(1, 'hello');

 console.log([...mapObject.entries()]);
 // [[1, "hello"]]

 console.log([...mapObject.keys()]);
 // [1]

 console.log([...mapObject.values()]);
 // ["hello"]

【讨论】:

【参考方案5】:

你可以使用console.log(mapObject.values())

【讨论】:

我在 CodePen 控制台中看到的只是[object Map Iterator] 【参考方案6】:

注意:此答案仅与 OP 正在使用的 repl.it 沙箱环境相关

既然您在 cmets 中说您正在使用 repl.it,那么您可以使用一个技巧来编写自己的“日志记录策略”。

请注意,您不应该在生产中使用此技巧,主要是因为它会编辑原生原型。在某些 Node 环境中,在您自己的代码中,它可能很有用。

我们的想法是为Map 创建一个inspect 方法,该方法迭代entries

Map.prototype.inspect = function() 
  return `Map($mapEntriesToString(this.entries()))`


function mapEntriesToString(entries) 
  return Array
    .from(entries, ([k, v]) => `\n  $k: $v`)
    .join("") + "\n";

你可以看到repl.it支持它here

console.log(new Map([["a", 1], ["b", 2]]));
// Logs:
/*
Map(
  a: 1
  b: 2
)
*/

【讨论】:

不错的一个。我刚刚完成了类似的事情,但我选择将他们的 console.log 混为一谈 :) repl.it/KBdU @DaveSalomon 不错!感觉就像“我们处于在线沙盒环境中;让我们打破所有原生原型和默认实现!” ;) 尽管如此,这两种方法都可以在调试过程中提供帮助,所以很高兴看到可以做什么。

以上是关于如何将 JavaScript ES6 映射对象显示到控制台?的主要内容,如果未能解决你的问题,请参考以下文章

每天一点点之javascript(ES6) - Map对象

ES6 将对象数组映射到数组

打字稿:如何根据对象键/值类型在 ES6 映射中创建条目

JavaScript:如何映射两个对象以获得将第一个对象的 ID 映射到另一个对象的名称的输出?

如何在不替换 ES6/Javascript 中的整个属性的情况下深度复制对象 [重复]

谈谈ES5和ES6的区别