如何用知名Symbol黑掉JavaScript(5种方法)

科技   2024-08-30 08:54   福建  

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

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

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

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

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

1. Symbol.hasInstance

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

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

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

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

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

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

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

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

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

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

2. Symbol.iterator

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

还记得这个吗:

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

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

每当我们使用for..of

这在幕后发生:

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

3. Symbol.toPrimitive

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

变成这个:

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

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

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

4. Symbol.split

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

5. Symbol.search

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

最后的思考

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

最后:
CSS技巧与案例详解
vue2与vue3技巧合集
VueUse源码解读

前端宇宙
种一棵树,最好的时间是十年前,其次是现在。
 最新文章