Symbol.toStringTag 是 ES6 中引入的 Symbol 类型之一,它的作用是为对象定义一个自定义的字符串类型的标识,用于 Object.prototype.toString() 方法的输出。在 ES7 中,Symbol.toStringTag 的功能得到了进一步增强,本文将介绍它的使用方法以及解决常见的 bug。
使用方法
我们首先来看一个简单的例子:
class Person {
get [Symbol.toStringTag]() {
return "Person";
}
}
const p = new Person();
console.log(p.toString()); // "[object Person]"在上面的例子中,我们定义了一个 Person 类,并为它设置了 Symbol.toStringTag 属性,返回了字符串 "Person"。当我们调用该对象的 toString() 方法时,会返回字符串 "[object Person]"。这里的 "Person" 字符串就是通过 Symbol.toStringTag 属性返回的。
当然,对于像 Array、Function、RegExp 等原生对象,它们已经实现了 Symbol.toStringTag 属性,我们也可以自行修改它们:
-- -------------------- ---- -------
----- --- - --- -- ---
------------------------------------------------- -- -------- -------
-------------------------------------- ------------------- -
---- ---------- -
------ ----------
-
---
------------------------------------------------- -- -------- ---------在上面的例子中,我们为 Array.prototype 添加了 Symbol.toStringTag 属性,返回值为 "MyArray",当我们调用 Object.prototype.toString.call(arr) 方法时,返回的字符串就变成了 "[object MyArray]"。这使我们可以更方便地输出自定义的字符串类型的标识。
常见 bug 及解决方法
尽管 Symbol.toStringTag 带来了很多方便,但它也有可能引起一些 bug,下面列举两个常见的情况以及解决方法。
1. 类被继承后,Symbol.toStringTag 属性失效
-- -------------------- ---- -------
----- ------ -
--- ---------------------- -
------ ---------
-
-
----- ------- ------- ------ --
----- - - --- ----------
-------------------------- -- -------- --------在上面的例子中,我们定义了一个 Person 类,并为它设置了 Symbol.toStringTag 属性,返回了字符串 "Person"。然后我们又定义了一个 Student 类,并继承自 Person 类。当我们调用 Student 实例的 toString() 方法时,会返回字符串 "[object Object]",这是因为 Student 类继承了 Person 类的 Symbol.toStringTag 属性,但没有进行覆盖。
解决此问题的简单方法是在 Student 类中再次定义 Symbol.toStringTag 属性,并返回类名即可:
class Student extends Person {
get [Symbol.toStringTag]() {
return "Student";
}
}
const s = new Student();
console.log(s.toString()); // "[object Student]"2. 调用 JSON.stringify() 方法时,Symbol.toStringTag 属性失效
class Person {
get [Symbol.toStringTag]() {
return "Person";
}
}
const p = new Person();
console.log(JSON.stringify(p)); // "{}"在上面的例子中,我们定义了一个 Person 类,并为它设置了 Symbol.toStringTag 属性,返回了字符串 "Person"。然后我们将 Person 类的实例 p 传递给 JSON.stringify() 方法进行序列化,但返回的结果为空对象 "{}"。这是因为 JSON.stringify() 方法会忽略 Symbol.toStringTag 属性。
解决此问题的方法是将 Symbol.toStringTag 属性添加到对象的 prototype 属性上:
-- -------------------- ---- -------
----- ------ -
--- ---------------------- -
------ ---------
-
-
------------------------------------ - ---------
----- - - --- ---------
------------------------------- -- -------------------------------------在上面的例子中,我们将 Symbol.toStringTag 属性添加到了 Person 类的 prototype 属性上,并赋值为 "Person"。现在当我们调用 JSON.stringify(p) 方法时,返回的结果包含了 Symbol.toStringTag 属性。
总结
在 ES7 中,Symbol.toStringTag 的功能得到了进一步增强,它可以帮助我们输出自定义的字符串类型的标识,使代码更加清晰易读。但使用过程中也有可能遇到一些问题,例如继承和 JSON 序列化时 Symbol.toStringTag 属性失效等。针对这些常见问题,我们可以通过简单的方法进行解决。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/65b0620dadd4f0e0ff9bd817