21

如何在 nodejs 调试控制台中更改对象实例的字符串表示形式。有没有toString()我可以覆盖的方法(比如在.NET中)?

在此处输入图像描述

考虑以下代码:

class SomeObject{
    constructor(){
        this._varA = "some text";
        this._varB = 12345;
        this._varC = "some more text";
        this._varD = true;
        this._varE = 0.45;
    }

    toString(){
        return "custom textual rapresentation of my object";
    }
}

var array = [];

array.push(new SomeObject());
array.push(new SomeObject());
array.push(new SomeObject());

console.log(array);

这会产生以下结果: 在此处输入图像描述

然而,在我研究过的其他环境和编程语言中,覆盖该toString()方法将显示toString()(在上面的示例中"custom textual representation of my object")的结果,而不是由调试器创建的动态文本表示(在上面的示例代码中是SomeObject {_varA: "some text", _varB: 12345, _varC: "some more text", …}:) - 我不这样做'不要怀疑一分钟,当未定义自定义替代方案时,它非常有用。

我也意识到console.log(array.toString());甚至console.log(array.map(t=>t.toString()));会产生类似于我所追求的东西,但是这会阻止我使用调试导航来导航对象,即。钻入对象图。

如果这不可能,其他人会从中受益吗?如果有足够的兴趣,我可以考虑将其定义和实现为一个特性。

4

5 回答 5

10

当你在console.log内部调用formatValueutil.js,它有一个下面的检查

const maybeCustomInspect = value[customInspectSymbol] || value.inspect;

这意味着如果您的值有一个inspect方法,它会被调用,然后您可以返回toString相同的方法。因此,将您的代码更改为

class SomeObject{
    constructor(){
        this._varA = "some text";
        this._varB = 12345;
        this._varC = "some more text";
        this._varD = true;
        this._varE = 0.45;
    }

    inspect(depth, opts) {
        return this.toString();
    }

    toString(){
        return "custom textual rapresentation of my object";
    }
}

var array = [];

array.push(new SomeObject());
array.push(new SomeObject());
array.push(new SomeObject());

console.log(array);

让它打印

[ custom textual rapresentation of my object,
  custom textual rapresentation of my object,
  custom textual rapresentation of my object ]

Nodejs 也有相同的文档

https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_custom_inspection_functions_on_objects

我使用的inspect方法根据文档已被弃用,正确的方法如下

const util = require('util');

class SomeObject{
    constructor(){
        this._varA = "some text";
        this._varB = 12345;
        this._varC = "some more text";
        this._varD = true;
        this._varE = 0.45;
    }

    [util.inspect.custom](depth, options) {
        return this.toString();
    }

    toString(){
        return "custom textual rapresentation of my object";
    }
}

var array = [];

array.push(new SomeObject());
array.push(new SomeObject());
array.push(new SomeObject());

console.log(array);

编辑:2018 年 3 月 28 日

所以我使用下面启动了脚本

$ node --inspect-brk=54223 test.js 
Debugger listening on ws://127.0.0.1:54223/81094440-716b-42a5-895e-4ea2008e0dff
For help see https://nodejs.org/en/docs/inspector

然后socat使用以下运行转发器

$ socat -v TCP-LISTEN:54222,fork TCP:127.0.0.1:54223

当您在调试器中调试变量时,您会在终端array上得到以下输出socat

索卡特

这些信息是由调试器重建的,为您提供有意义的表示。

现在v8调试 api 不知道我们想要以不同的方式表示它,就像我们为console.log. 现在代码中可能有类似的东西做类似的V8事情,但是查看源代码,我无法弄清楚是否存在这样的事情。因此,您可能需要向具有 V8 调试器 api 知识的人确认,如果存在此类问题

如果不是,您需要在 IDE 级别构建一些东西,这又不是一件容易的事

于 2018-03-24T05:58:09.727 回答
2

VS Code 中添加了一个新选项以启用调整调试器输出:只需将以下内容添加到您的启动配置中

"customDescriptionGenerator": "function (def) { if (this.toString) { const _v = this.toString(); if (_v.indexOf(\"[object Object]\") < 0) return _v; } return def; }",

Viola:在手表中使用“toString”查看您的实体,保留向下钻取等功能。

于 2020-12-17T16:54:55.570 回答
0

我的两分钱:如何覆盖 console.log 函数来做你想做的事。这是 POC,它需要任何对象中的 _toString 函数来更改它在日志中的显示方式。

创建一个包含以下内容的文件 logger.js:

const getUpdatedLogObj = function(x){


    if(x && typeof x == 'object'){
            if(typeof x._toString === 'function'){
                return x._toString()
            } else {
                for(let i in x){
                    x[i] = getUpdatedLogObj(x[i])
                }
            }
        }
        return x;
    }



    console._log = console.log
    console.log = function(x){console._log(getUpdatedLogObj({...x}))}

将其导入 index.js

require('./logger')

console.log({a: 1, b: 2, c: {d: 5, e: 6, _toString: function(){return 'fromToString'}}})

你仍然可以得到导航: 在此处输入图像描述

于 2018-03-28T15:40:41.173 回答
-1
const util = require('util');
class SomeObject{
constructor(){
    this._varA = "some text";
    this._varB = 12345;
    this._varC = "some more text";
    this._varD = true;
    this._varE = 0.45;
}

[util.inspect.custom](depth, options) {
    return this.toString();
}

toString(){
    return "custom textual rapresentation of my object";
}
}

var array = [];

array.push(new SomeObject());
array.push(new SomeObject());
array.push(new SomeObject());

console.log(array);
于 2018-03-28T15:46:25.907 回答
-2

您可以在另一个字符串上调用一个 toString() 方法。

terms[200]._text.toString()

您可能还在寻找JSON.stringify()我认为在调试中非常有用的东西。由于 JavaScript 对象实际上是 JSON,这将使它们更简单地打印到控制台。

console.log(JSON.stringify(terms[200]))

于 2018-03-23T03:36:19.177 回答