是否可以覆盖 JavaScript 的 toString() 函数来为调试提供有意义的输出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6307514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to override JavaScript's toString() function to provide meaningful output for debugging?
提问by devios1
When I console.log()
an object in my JavaScript program, I just see the output [object Object]
, which is not very helpful in figuring out what object (or even what type of object) it is.
当我console.log()
在 JavaScript 程序中创建一个对象时,我只看到输出[object Object]
,这对于确定它是什么对象(甚至是什么类型的对象)并不是很有帮助。
In C# I'm used to overriding ToString()
to be able to customize the debugger representation of an object. Is there anything similar I can do in JavaScript?
在 C# 中,我习惯于重写ToString()
以便能够自定义对象的调试器表示。我可以在 JavaScript 中做类似的事情吗?
采纳答案by Michael Spector
You can override toString
in Javascript as well. See example:
您也可以toString
在 Javascript 中进行覆盖。见示例:
function Foo()
{
}
// toString override added to prototype of Foo class
Foo.prototype.toString = function()
{
return "[object Foo]";
}
var f = new Foo();
alert(f); // popup displays [object Foo]
See thisdiscussion on how to determine object type name in JavaScript.
见这对如何在JavaScript中确定对象类型名称的讨论。
回答by Max Heiber
First override toString
for your object or the prototype:
首先覆盖toString
您的对象或原型:
var Foo = function(){};
Foo.prototype.toString = function(){return 'Pity the Foo';};
var foo = new Foo();
Then convert to string to see the string representation of the object:
然后转换为字符串,查看对象的字符串表示:
//using JS implicit type conversion
console.log('' + foo);
If you don't like the extra typing, you can create a function that logs string representations of its arguments to the console:
如果您不喜欢额外的输入,您可以创建一个函数,将其参数的字符串表示形式记录到控制台:
var puts = function(){
var strings = Array.prototype.map.call(arguments, function(obj){
return '' + obj;
});
console.log.apply(console, strings);
};
Usage:
用法:
puts(foo) //logs 'Pity the Foo'
puts(foo, [1,2,3], {a: 2}) //logs 'Pity the Foo 1,2,3 [object Object]'
Update
更新
E2015 provides much nicer syntax for this stuff, but you'll have to use a transpiler like Babel:
E2015 为这些东西提供了更好的语法,但你必须使用像Babel这样的转译器:
// override `toString`
class Foo {
toString(){
return 'Pity the Foo';
}
}
const foo = new Foo();
// utility function for printing objects using their `toString` methods
const puts = (...any) => console.log(...any.map(String));
puts(foo); // logs 'Pity the Foo'
回答by Paul V
An easy way to get debuggable output in browser JS is to just serialize the object to JSON. So you could make a call like
在浏览器 JS 中获得可调试输出的一种简单方法是将对象序列化为 JSON。所以你可以像这样打电话
console.log ("Blah: " + JSON.stringify(object));
So for an example, alert("Blah! " + JSON.stringify({key: "value"}));
produces an alert with the text Blah! {"key":"value"}
因此,例如,alert("Blah! " + JSON.stringify({key: "value"}));
生成带有文本的警报Blah! {"key":"value"}
回答by SystematicFrank
If you are using Node it might be worth considering util.inspect
.
如果您正在使用 Node,则可能值得考虑util.inspect
。
var util = require('util')
const Point = {
x: 1,
y: 2,
[util.inspect.custom]: function(depth) { return `{ #Point ${this.x},${this.y} }` }
}
console.log( Point );
This will yield:
这将产生:
{ #Point 1,2 }
While the version without inspect prints:
而没有检查打印的版本:
{ x: 1, y: 2 }
回答by Matt Ball
Just override the toString()
method.
只需覆盖该toString()
方法。
Simple example:
简单的例子:
var x = {foo: 1, bar: true, baz: 'quux'};
x.toString(); // returns "[object Object]"
x.toString = function () {
var s = [];
for (var k in this) {
if (this.hasOwnProperty(k)) s.push(k + ':' + this[k]);
}
return '{' + s.join() + '}';
};
x.toString(); // returns something more useful
It does even better when you define a new type:
当你定义一个新类型时它会做得更好:
function X()
{
this.foo = 1;
this.bar = true;
this.baz = 'quux';
}
X.prototype.toString = /* same function as before */
new X().toString(); // returns "{foo:1,bar:true,baz:quux}"
回答by Hacked Child
If the object is defined by yourself you can always add a toString override.
如果对象是由你自己定义的,你总是可以添加一个 toString 覆盖。
//Defined car Object
var car = {
type: "Fiat",
model: 500,
color: "white",
//.toString() Override
toString: function() {
return this.type;
}
};
//Various ways to test .toString() Override
console.log(car.toString());
console.log(car);
alert(car.toString());
alert(car);
//Defined carPlus Object
var carPlus = {
type: "Fiat",
model: 500,
color: "white",
//.toString() Override
toString: function() {
return 'type: ' + this.type + ', model: ' + this.model + ', color: ' + this.color;
}
};
//Various ways to test .toString() Override
console.log(carPlus.toString());
console.log(carPlus);
alert(carPlus.toString());
alert(carPlus);
回答by sami
With template literals:
使用模板文字:
class Foo {
toString() {
return 'I am foo';
}
}
const foo = new Foo();
console.log(`${foo}`); // 'I am foo'
回答by Danield
Add the 'Symbol.toStringTag'property to the custom object or class.
将“Symbol.toStringTag”属性添加到自定义对象或类。
The string value which is assigned to it will be its default string description because it is accessed internally by the Object.prototype.toString()
method.
分配给它的字符串值将是它的默认字符串描述,因为它是由Object.prototype.toString()
方法内部访问的。
For example:
例如:
class Person {
constructor(name) {
this.name = name
}
get [Symbol.toStringTag]() {
return 'Person';
}
}
let p = new Person('Dan');
Object.prototype.toString.call(p); // [object Person]
class Person {
constructor(name) {
this.name = name
}
get[Symbol.toStringTag]() {
return 'Person';
}
}
let p = new Person('Dan');
console.log(Object.prototype.toString.call(p));
Some Javascript types such as Maps and Promises have a built-in toStringTag
symbol defined
某些 Javascript 类型(例如 Maps 和 Promises)toStringTag
定义了内置符号
Object.prototype.toString.call(new Map()); // "[object Map]"
Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"
Because Symbol.toStringTag
is a well-known symbol, we can reference it and verify that the above types do have the Symbol.toStringTag property -
因为Symbol.toStringTag
是一个众所周知的符号,我们可以引用它并验证上述类型确实具有 Symbol.toStringTag 属性 -
new Map()[Symbol.toStringTag] // 'Map'
Promise.resolve()[Symbol.toStringTag] // 'Promise'
回答by jmojico
-This operation takes lot of time to complete, and it's use is discouraged according to mozilla docs: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/proto
- 此操作需要大量时间才能完成,根据 mozilla 文档不鼓励使用:https: //developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/proto
-Apparently, modern browsers deprecated .prototype and ECMA6 specifies using proper__proto__ instead.
-显然,现代浏览器已弃用 .prototype 并且 ECMA6 指定使用正确的__proto__ 代替。
So for example, if you are defining you own object geopositionyou should call __proto__property instead of .prototype:
因此,例如,如果要定义你自己的对象geoposition你应该叫__proto__属性,而不是.prototype:
var geoposition = {
lat: window.pos.lat,
lng: window.pos.lng
};
geoposition.__proto__.toString = function(){ return "lat: "+this.lat+", lng: "+this.lng }
console.log("Searching nearby donations to: "+geoposition.toString());
回答by Agustí Sánchez
Here's an example how to stringify a Map object:
这是一个如何字符串化 Map 对象的示例:
Map.prototype.toString = function() {
let result = {};
this.forEach((key, value) => { result[key] = value;});
return JSON.stringify(result);
};