console.log中的%j特定符号会排除一些属性。

17

最近我尝试在node.js中加载bson(二进制JSON)模块。由于API文档不清楚,所以我想检查对象来帮助自己。但检查结果让我感到困惑。

最终我发现问题出在我使用了%j,它会“欺骗”我——它不会打印对象字典键的所有内容!(在JS中,我使用Python术语表示“属性”指的是用点引用的事物,“字典键”指的是用括号引用的事物,因为我不知道这些事物的正确名称。)

这里是一个例子:

var bson = require("bson");
console.log("bson as %%j: %j", bson);
console.log("bson as console.log: ", bson);

这是输出结果:

bson as %j: {"BSONPure":{},"BSONNative":{}}
bson as console.log:  { BSONPure: 
   { Code: [Function: Code],
     Symbol: [Function: Symbol],
     BSON: 
      { [Function: BSON]
        BSON_INT32_MAX: 2147483647,
        BSON_INT32_MIN: -2147483648,
        BSON_INT64_MAX: 9223372036854776000,
        BSON_INT64_MIN: -9223372036854776000,
...

我认为由于x.keyx["key"]相同,这意味着JS中的属性和字典键是“同一回事”。然而,我在尝试后发现BSON.BSONPure{},但是BSON.BSONPure.BSONBSON.BSONPure["BSON"]却是一个function对象!

这让我相信,无论"%j"做了什么,肯定会排除某些键。它如何决定排除哪些键?为什么要这样做?有时候JS真的很令人困惑!

相关Github问题:https://github.com/mongodb/js-bson/issues/97


两个东西是一样的(就像你所说的,x.keyx["key"]完全等价),它们被称为属性 - Bergi
1个回答

32

node.js源代码中,%j 占位符会对传递的参数调用 JSON.stringify() 方法。

问题是,在传递你的 bson 变量时,你没有传递一个有效的 JSON 对象,而是传递了一个 node.js 模块,其中包括导出函数等内容。

那么,当 JSON.stringify() 遇到函数时会发生什么呢?

如果转换过程中遇到未定义、函数或符号,则在对象中找到时将被省略,在数组中找到时将被替换为 null。(MDN

因此,你看到的行为完全是预期的,你正在尝试记录一个不是有效的 JSON 的东西。

> JSON.stringify({name: "Bob"}) 
> "{"name":"Bob"}"

> JSON.stringify({func: function(){}}) 
> "{}"

2
我猜这是有道理的。当我打印一些对象时,我尝试使用console.log("x is "+x),但它只给出了无用的x is [object Object]。所以我在谷歌上搜索了如何在JS中打印输出,我看到的答案告诉我要使用%j,这对于特定的示例起作用。但后来我开始将%j用作“Python repr()的JS版本”,而没有实际阅读它的功能。感谢您提供文档的参考。 - picomancer
引用的 node.js 源文件已更改。这似乎是最后一次编辑时可能是版本的规范URL:https://github.com/nodejs/node/blob/3e44b8c91ef717913364ac67a12cb7cd638630db/lib/util.js#L280 - Rohan Talip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接