如何在 Nodejs 调试控制台视图中更改对象的字符串表示 [英] How to change string representation of objects in Nodejs debug console view

查看:22
本文介绍了如何在 Nodejs 调试控制台视图中更改对象的字符串表示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

考虑以下代码:

class SomeObject{构造函数(){this._varA = "一些文字";this._varB = 12345;this._varC = "更多文字";this._varD = true;this._varE = 0.45;}toString(){返回我的对象的自定义文本表示";}}var 数组 = [];array.push(new SomeObject());array.push(new SomeObject());array.push(new SomeObject());控制台日志(数组);

这会产生以下结果:

但是在我使用过的其他环境和编程语言中,覆盖 toString() 方法将显示 toString() 的结果(在上面的示例中 我的对象的自定义文本表示")而不是调试器创建的动态文本表示(在上面的示例代码中,这是: SomeObject {_varA: "some text", _varB: 12345, _varC: "some more text", ...}) - 我毫不怀疑这在没有定义自定义替代方案时非常有用.

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

如果这是不可能的,其他人会从中受益吗?如果有足够的兴趣,我可以考虑将其定义为功能并将其实现.

解决方案

当你做 console.log 时,它会在 util.js 内部调用 formatValue代码>,有一个下面的检查

const MaybeCustomInspect = value[customInspectSymbol] ||值.检查;

这意味着如果您的值有一个 inspect 方法,它会被调用,然后您可以在相同的情况下返回 toString .所以把你的代码改成

class SomeObject{构造函数(){this._varA = "一些文字";this._varB = 12345;this._varC = "更多文字";this._varD = true;this._varE = 0.45;}检查(深度,选择){返回 this.toString();}toString(){返回我的对象的自定义文本表示";}}var 数组 = [];array.push(new SomeObject());array.push(new SomeObject());array.push(new SomeObject());控制台日志(数组);

打印出来

[ 我的对象的自定义文本表示,我的对象的自定义文本表示,我的对象的自定义文本表示]

Nodejs 也有相关文档

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

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

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

How do I change the string representation of an object instance in nodejs debug console. Is there a method (like toString() in .NET) I can override?

Consider the following code:

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);

This produces the following:

However in other environments and programming languages I have worked on, overriding the toString() method would show the result of toString() (in the example above "custom textual representation of my object") instead of the dynamic textual representation created by the debugger (in the example code above this is: SomeObject {_varA: "some text", _varB: 12345, _varC: "some more text", …}) - which I don't doubt for one minute it is very useful when a custom alternative is not defined.

I also realise that console.log(array.toString()); or even console.log(array.map(t=>t.toString())); will produce something similar to what I am after, however this then prevents me to navigate through the objects using the debug navigation ie. drill into the object graph.

If this is not possible, would others benefit from this? If there is enough interest, I can look into defining and implementing it as a feature.

解决方案

When you do console.log it internally calls formatValue in util.js, which has a below check

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

Which means if your value has a inspect method it gets called and then you can return the toString in the same. So change your code to

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);

Makes it print

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

Nodejs has documentation on the same too

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

The inspect method I used is deprecated as per documentation and the correct way to do it is below

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);

Edit: 28th-Mar-2018

So I launched the script using below

$ 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

And then ran a socat forwarder using below

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

When you debug the variable array in debugger, you get below output on the socat terminal

The information is that reconstructed by debugger to give you a meaningful representation.

Now the v8 debug api has no idea that we want to represent it differently, like we did for console.log. Now there may be something similar in V8 code that does something similar, but looking at the source code, I was not able to figure out there exists such a thing. So you may need to confirm from someone who has V8 debugger api knowledge, if something of this sort exists

If not the you need to construct something at the IDE level, which again is not a a easy thing to do

这篇关于如何在 Nodejs 调试控制台视图中更改对象的字符串表示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆