是否可能覆盖JavaScript的toString()函数以提供有意义的输出用于调试?

34 浏览
0 Comments

是否可能覆盖JavaScript的toString()函数以提供有意义的输出用于调试?

在我的 JavaScript 程序中,当我使用 console.log() 输出一个对象时,我只能看到 [object Object],这对于确定对象(甚至是对象的类型)不是很有帮助。

在 C# 中,我习惯于重写 ToString() 来自定义对象的调试器表示。在 JavaScript 中有类似的方法吗?

0
0 Comments

在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]"的效果。

至于是否有其他方法可以实现这个效果,目前我认为这是唯一的方式。如果还有其他方法,请告诉我 😉

这个方法适用于最近三四年编写的任何代码。此外,在单元测试中模拟类时,这也非常有用,可以检查实例化对象的类型。

0
0 Comments

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/…

0
0 Comments

在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还提供了更简洁的语法来实现相同的功能。

0