简体   繁体   English

如何让 console.log 输出 getter 结果而不是字符串“[Getter/Setter]”?

[英]How can I get console.log to output the getter result instead of the string "[Getter/Setter]"?

In this code:在这段代码中:

function Cls() {
    this._id = 0;
    Object.defineProperty(this, 'id', {
        get: function() {
            return this._id;
        },
        set: function(id) {
            this._id = id;
        },
        enumerable: true
    });
};
var obj = new Cls();
obj.id = 123;
console.log(obj);
console.log(obj.id);

I would like to get { _id: 123, id: 123 } but instead I get { _id: 123, id: [Getter/Setter] }我想得到 { _id: 123, id: 123 } 但我得到的是 { _id: 123, id: [Getter/Setter] }

Is there a way to have the getter value be used by the console.log function?有没有办法让 console.log 函数使用 getter 值?

您可以使用console.log(Object.assign({}, obj));

使用console.log(JSON.stringify(obj));

You can define an inspect method on your object, and export the properties you are interested in. See docs here: https://nodejs.org/api/util.html#util_custom_inspection_functions_on_objects您可以在您的对象上定义一个inspect方法,并导出您感兴趣的属性。请参阅此处的文档: https : //nodejs.org/api/util.html#util_custom_inspection_functions_on_objects

I guess it would look something like:我想它看起来像:

function Cls() {
    this._id = 0;
    Object.defineProperty(this, 'id', {
        get: function() {
            return this._id;
        },
        set: function(id) {
            this._id = id;
        },
        enumerable: true
    });
};

Cls.prototype.inspect = function(depth, options) {
    return `{ 'id': ${this._id} }`
}

var obj = new Cls();
obj.id = 123;
console.log(obj);
console.log(obj.id);

Since Nodejs v11.5.0 you can set getters: true in the util.inspect options.从 Nodejs v11.5.0 开始,您可以在util.inspect选项中设置getters: true See here for docs . 有关文档,请参见此处

getters <boolean> | getters <boolean> | <string> If set to true, getters are inspected. <string> 如果设置为 true,则检查 getter。 If set to 'get', only getters without a corresponding setter are inspected.如果设置为 'get',则只检查没有相应设置器的 getter。 If set to 'set', only getters with a corresponding setter are inspected.如果设置为“set”,则仅检查具有相应设置器的 getter。 This might cause side effects depending on the getter function.这可能会导致副作用,具体取决于 getter 函数。 Default: false.默认值:假。

I needed a pretty printed object without the getters and setters yet plain JSON produced garbage.我需要一个漂亮的打印对象,没有 getter 和 setter,但纯 JSON 会产生垃圾。 For me as the JSON string was just too long after feeding JSON.stringify() a particularly big and nested object.对我来说,在将JSON.stringify()给一个特别大的嵌套对象后,JSON 字符串太长了。 I wanted it to look like and behave like a plain stringified object in the console.我希望它在控制台中看起来和行为都像一个普通的字符串化对象。 So I just parsed it again:所以我只是再次解析它:

JSON.parse(JSON.stringify(largeObject))

There.那里。 If you have a simpler method, let me know.如果你有更简单的方法,请告诉我。

On Node.js, I suggest using util.inspect.custom , which will allow you to pretty print getters as values, while keeping other properties output unchanged.在 Node.js 上,我建议使用util.inspect.custom ,这将允许您将 getter 漂亮地打印为值,同时保持其他属性输出不变。

It will apply to your specific object only and won't mess the general console.log output.它仅适用于您的特定对象,不会弄乱一般的 console.log 输出。

The main benefit vs Object.assign is that it happens on your object, so you keep the regular generic console.log(object) syntax.Object.assign的主要好处是它发生在您的对象上,因此您可以保留常规的通用console.log(object)语法。 You don't have to wrap it with console.log(Object.assign({}, object)) .您不必用console.log(Object.assign({}, object))包装它。

Add the following method to your object:将以下方法添加到您的对象中:

[util.inspect.custom](depth, options) {
    const getters = Object.keys(this);
    /*
        for getters set on prototype, use instead:
        const prototype = Object.getPrototypeOf(this);
        const getters = Object.keys(prototype);
    */
    const properties = getters.map((getter) => [getter, this[getter]]);
    const defined = properties.filter(([, value]) => value !== undefined);
    const plain = Object.fromEntries(defined);
    const object = Object.create(this, Object.getOwnPropertyDescriptors(plain));
    // disable custom after the object has been processed once to avoid infinite looping
    Object.defineProperty(object, util.inspect.custom, {});
    return util.inspect(object, {
        ...options,
        depth: options.depth === null ? null : options.depth - 1,
    });
}

Here is a working example in your context:这是您的上下文中的一个工作示例:

const util = require('util');

function Cls() {
    this._id = 0;
    Object.defineProperty(this, 'id', {
        get: function() {
            return this._id;
        },
        set: function(id) {
            this._id = id;
        },
        enumerable: true
    });
    this[util.inspect.custom] = function(depth, options) {
    const getters = Object.keys(this);
    /*
        for getters set on prototype, use instead:
        const prototype = Object.getPrototypeOf(this);
        const getters = Object.keys(prototype);
    */
    const properties = getters.map((getter) => [getter, this[getter]]);
    const defined = properties.filter(([, value]) => value !== undefined);
    const plain = Object.fromEntries(defined);
    const object = Object.create(this, Object.getOwnPropertyDescriptors(plain));
    // disable custom after the object has been processed once to avoid infinite looping
    Object.defineProperty(object, util.inspect.custom, {});
    return util.inspect(object, {
        ...options,
        depth: options.depth === null ? null : options.depth - 1,
    });
}
};
var obj = new Cls();
obj.id = 123;
console.log(obj);
console.log(obj.id);

Output:输出:

Cls { _id: 123, id: 123 }
123

Use spread operator console.log({... obj });使用传播运算符 console.log({... obj });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM