是否可能覆盖JavaScript的toString()函数以提供有意义的输出用于调试?
在JavaScript中,使用toString()函数可以将一个对象转换为字符串表示形式。然而,默认情况下,这个函数返回的结果通常并不直观,对于调试来说并没有太多帮助。因此,有时候我们希望能够重写这个函数,以便为调试提供有意义的输出。
解决这个问题的方法是通过在自定义对象或类中添加Symbol.toStringTag属性。这个属性的字符串值将成为对象的默认字符串描述,因为它在内部被Object.prototype.toString()方法访问到。
下面是一个示例:
class Person { constructor(name) { this.name = name } get [Symbol.toStringTag]() { return 'Person'; } } let p = new Person('Dan'); console.log(Object.prototype.toString.call(p)); // [object Person]
上述代码中,我们在Person类中添加了Symbol.toStringTag属性,并返回字符串'Person'。然后,通过调用Object.prototype.toString()方法,并传入我们创建的Person对象p作为参数,可以看到输出结果为'[object Person]'。
除此之外,一些JavaScript类型,如Map和Promise,已经内置了toStringTag属性。可以通过调用Object.prototype.toString()方法来查看它们的默认字符串描述。
Object.prototype.toString.call(new Map()); // "[object Map]" Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"
由于Symbol.toStringTag是一个内置的well-known symbol,我们可以引用它并验证上述类型是否具有Symbol.toStringTag属性。
new Map()[Symbol.toStringTag] // 'Map' Promise.resolve()[Symbol.toStringTag] // 'Promise'
通过以上方法,我们可以实现类似于函数MyObj的输出结果为"[object MyObj]"的效果。
至于是否有其他方法可以实现这个效果,目前我认为这是唯一的方式。如果还有其他方法,请告诉我 😉
这个方法适用于最近三四年编写的任何代码。此外,在单元测试中模拟类时,这也非常有用,可以检查实例化对象的类型。
JavaScript中的toString()函数可以被重写以提供有意义的调试输出。如下所示,可以重写toString()函数:
function Foo() {} // 在Foo类的原型中添加toString()重写 Foo.prototype.toString = function() { return "[object Foo]"; } var f = new Foo(); console.log("" + f); // 控制台显示 [object Foo]
参考这个讨论了如何确定JavaScript中对象类型名称的问题。
尽管alert函数将显示重写原型toString()属性的函数的返回值,但Object.prototype.toString.call(f)仍然显示[object Object]。
'Object.prototype.toString.call(f)仍然显示[object Object]。'是因为这与'Foo.prototype.toString'是完全不同的函数,哈哈。
如果其他人和我一样遇到这个问题,可以使用ES6中的Symbol.toStringTag来自定义Object.prototype.toString.call的行为。参考developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。
在JavaScript中,toString()函数用于将对象转换为字符串表示。默认情况下,toString()函数返回的是对象的类型和内存地址,对于调试和输出目的来说并不是很有用。因此,有时候我们希望能够自定义toString()函数,以提供更有意义的输出。
为了实现这一点,我们可以重写对象或原型的toString()函数。首先定义一个对象或原型,然后在其中重写toString()函数,返回我们想要的字符串表示。例如:
var Foo = function(){}; Foo.prototype.toString = function(){return 'Pity the Foo';}; var foo = new Foo();
然后,我们可以将对象转换为字符串以查看其字符串表示。可以使用隐式类型转换,将对象与一个空字符串相加,例如:
console.log('' + foo);
如果不想每次都进行这样的操作,我们可以创建一个函数,该函数将其参数的字符串表示输出到控制台。这个函数可以使用map()方法将参数转换为字符串数组,然后使用apply()方法将字符串数组作为参数传递给console.log()函数。例如:
var puts = function(){ var strings = Array.prototype.map.call(arguments, function(obj){ return '' + obj; }); console.log.apply(console, strings); };
使用示例:
puts(foo); // 输出 'Pity the Foo' puts(foo, [1,2,3], {a: 2}); // 输出 'Pity the Foo 1,2,3 [object Object]'
更新:ES2015提供了更简洁的语法来实现这一点,但是需要使用像Babel这样的转译器进行转换。可以使用类和箭头函数来实现相同的功能。例如:
class Foo { toString(){ return 'Pity the Foo'; } } const foo = new Foo(); const puts = (...any) => console.log(...any.map(String)); puts(foo); // 输出 'Pity the Foo'
通过重写JavaScript的toString()函数,我们可以提供有意义的输出来进行调试和日志记录。可以通过重写对象或原型的toString()函数来实现这一点,或者创建一个函数来自动转换对象为字符串并输出到控制台。ES2015还提供了更简洁的语法来实现相同的功能。