开发者

Is there a method I can override on a JavaScript object to control what is displayed by console.log?

开发者 https://www.devze.com 2023-01-02 05:42 出处:网络
I\'m thinking in particular of Chrome, though Firebug would be interesting to.I\'ve tried toString() and valueOf(), but neither of those see开发者_如何学Cm to be used.Interestingly, if I take a functi

I'm thinking in particular of Chrome, though Firebug would be interesting to. I've tried toString() and valueOf(), but neither of those see开发者_如何学Cm to be used. Interestingly, if I take a function it'll display the function definition - but then if I add a toString() method it will show null!

var a = function(){};
console.log(a); // output: function (){}
a.toString = function(){ return 'a'; };
console.log(a); // output: null
a.valueOf = function(){ return 'v'; };
console.log(a); // output: null

Any ideas?


There's no way I know of. Your best bet will be to define a toString() method on the object you want to log and then call it, either directly or indirectly:

var o = {};
o.toString = function() {
    return "Three blind mice";
};

console.log("" + o);
console.log(o.toString());


Just for future readers, there is now a way to do exactly what is asked here.

For the solution please read this duplicated post:

adjust console.log behaviour of custom object


You can do this in Chrome nowadays with a devtools custom formatter. They don't seem to be officially documented anywhere, and aren't enabled by default -- so you have to enable them in (Dev Tools Settings) > Console > Enable Custom Formatters. But then you can add a custom formatter for your object:

class CustomClass {
    constructor (foo, bar) { this.foo = foo; this.bar = bar; }
}

window.devtoolsFormatters = (window.devtoolsFormatters || []).concat([{
    header: (obj) => {
        if (obj instanceof CustomClass) {
            return ['div', {}, `CustomClass(${obj.foo}, ${obj.bar})`];
        } else {
            return null; // fall back to default formatter
        }
    },
    hasBody: () => true, // if the user can expand to get more info
    body: (obj) => {
        return ['div', {},
            ['span', {style: 'display: block; font-weight: bold'}, 'CustomClass'],
            ['span', {style: 'display: block; margin-left: 2em'}, `foo: ${obj.foo}`],
            ['span', {style: 'display: block; margin-left: 2em'}, `bar: ${obj.bar}`],
        ];
    }
}]);

A few words of warning:

  • You must return a JsonML ([tag-name, attrs, children...]) list from the formatter. If you return an invalid JsonML or a bare string, it will either fail silently or throw an error.
  • The formatter must have a header() and hasBody() function, and if hasBody() returns true, must have a body() function as well. Otherwise your formatter will be either silently ignored or throw an error.
  • A lot of element types aren't supported. I was only able to get div and span to work; p, strong, and other elements all failed. But you can emulate them with CSS.
  • The window.devtoolsFormatters array is null by default, but I added the check because extensions may already add their own custom formatters.

You can find a bit more information here: https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/preview


You should get a better result from Firebug, you should get

var a = function(){};
console.log(a); // output: function 
a.toString = function(){ return 'a'; };
console.log(a); // output: function, {toString()}
a.valueOf = function(){ return 'v'; };
console.log(a); // output: function, {toString(), valueOf()}

http://code.google.com/p/fbug/issues/detail?id=3117

0

精彩评论

暂无评论...
验证码 换一张
取 消