1

他们称之为知名符号 — 尽管大多数开发者从未使用过它们,甚至从未听说过它们。

这是一个非常酷的功能,你可以用它来实现这样的魔法:

image.png

image.png

你将看到我们如何使用知名 Symbol 构建这些类来实现这一点。

它们全都是关于完全定制内置操作(如for..of)的正常行为。这就像C++和C#中的运算符重载。

它们也都是Symbol类的静态方法。

1. Symbol.hasInstance

首先我们有Symbol.hasInstance:用于轻松改变instanceof运算符的行为。

image.png

通常,instanceof用于检查一个变量是否是某个类的实例。

image.png

就像它应该的那样;相当标准的东西。

但是使用Symbol.hasInstance,我们可以完全改变instanceof的工作方式:

image.png

现在就instanceof而言,一个Person不再是Person了。

image.png

如果我们不想完全覆盖它,而是以一种直观的方式扩展它呢?

我们不能在 Symbol 内部使用instanceof,因为那会很快导致无限递归:

class Person {
  static [Symbol.hasInstance](instance) {
    return instance instanceof Person; // 无限递归!
  }
}

image.png

相反,我们将对象的特殊constructor属性与我们自己的进行比较:

image.png

如果你刚刚听说.constructor,这应该解释一切:

image.png

2. Symbol.iterator

我们的下一个黑客技巧是Symbol.iterator,用于完全改变循环如何以及是否在对象上工作。

还记得这个吗:

image.png

我们通过Symbol.iterator实现了这一点:

image.png

我们再次看到生成器出现。

每当我们使用for..of

image.png

这在幕后发生:

image.png

因此,通过Symbol.iterator,我们完全改变了for..of对任何List对象的操作:

image.png

image.png

3. Symbol.toPrimitive

使用Symbol.toPrimitive,我们可以快速从这个:

image.png

变成这个:

image.png

我们通过覆盖Symbol.toPrimitive实现了这一点:

image.png

现在我们可以在任何使用字符串进行插值和连接的地方使用Person对象:

image.png

甚至还有一个hint参数,可以使对象表现得像numberstring或其他东西。

image.png

4. Symbol.split

天才的知名 Symbol,用于将你的自定义对象转换为字符串分隔符:

image.png

5. Symbol.search

就像Symbol.split一样,将你的自定义对象转换为复杂的字符串搜索工具:

image.png

最后的思考

从循环到分割再到搜索,知名符号让我们可以重新定义我们的核心功能,使它们以独特和令人愉快的方式运行,推动了JavaScript可能性的边界。

首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑问?我来回答

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。


王大冶
68k 声望104.9k 粉丝