Skip to content

[译] 在 JavaScriptCore 中对变量、对象和函数进行格式化打印

Published: at 12:00编辑

原文标题:Pretty-Printing Variables, Objects, and Functions in JavaScriptCore

原文链接:https://christiantietze.de/posts/2024/07/pretty-printing-javascriptcore/

原文作者:Christian

本文译者:liuzhen932,首发于 liuzhen932 的小窝

默认情况下,JavaScriptCore 中JSValue的字符串输出(例如,通过我的 console.log)只会生成一个简单的[object Object],这并不太有用。

通过 JSON,可以很容易地对对象进行格式化打印(如果它们只是数据容器):

const obj = { a: 123, b: 456 };
JSON.stringify(obj, null, 4 /* 缩进级别 */);
// =>
// {
//     a: 123,
//     b: 456
// }

然而,这种方法无法打印函数。

在 JavaScript 中,任何函数都可以转换为字符串并直接打印,因此可以轻松实现这一点:

function addTwo(x) {
  return x + 2;
}
addTwo; // => 不调用,仅引用函数
// => function addTwo(x) {
//       return x + 2;
//    }

在我的研究中,我发现了一个 2005 年的旧 JavaScript dump 函数,它可以手动遍历对象并打印键值对。借助更现代的 ECMAScript 6 功能,可以使用以下代码打印类似 JSON 的对象,同时包含函数:

function dump(obj, level = 0) {
  if (typeof obj === "object" && obj !== null) {
    const indent = "  ".repeat(level + 1);
    const entries = Object.entries(obj).map(([key, value]) => {
      let entry = `${indent}"${key}": `;
      if (typeof value === "object" && value !== null) {
        entry += dump(value, level + 1).trim();
      } else if (typeof value === "string") {
        entry += `"${value}"`;
      } else {
        entry += `${value}`;
      }
      return entry;
    });

    const joinedEntries = entries.join(",\n");
    const levelPadding = "  ".repeat(level);
    return `{ \n${joinedEntries}\n${levelPadding}}`;
  } else {
    return `${obj} (${typeof obj})`;
  }
}

用法:

const obj = {
  f: (x) => x + 4,
  a: 123,
  b: { ba: 555, bb: "hello" },
};
dump(obj);
// =>
// {
//      'f': (x) => x + 4,
//      'a': 123,
//      'b': {
//        'ba': 555,
//        'bb': "hello"
//      }
//    }

这会生成一个字符串表示形式,该表示本身在执行时是有效的 JavaScript:

eval(`(${dump(obj)})`).f(1); // => 5

可能已经有一个 Node 包能实现这一点并做得更多,但对我来说,这足以通过我的应用程序中的 REPL 从 JavaScriptCore 内部检查对象。


上一篇
继续提速!我对网页优化的建议
下一篇
从实践中学习:我的云服务器管理策略

人机验证:请刷新页面以加载评论区