使用Symbol来Hack你的Javascript

288 阅读2分钟

介绍五种方式,大多数开发者从未使用过它们,甚至没有听说过。

一个你可以用来实现这种魔法的非常酷的功能

1_6wRAZzG9wVP49C33L0dCnA.webp

0_LcMiVEZYchKkgq6u.png

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

它们的全部内容都是关于完全定制内置操作的正常行为,比如 for..of。这就像在 C++ 和 C# 中的操作符重载一样。

还有 Symbol 类的所有静态方法。

1. Symbol.hasInstance

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

1_6ANCoLhUbrhxxfkCvmoTpw.png

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

1_8iMsgSpjJ6RDGtB7mV5OHw.png

正如它应该的那样;非常标准的东西。

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

1_9dy1KfcJKWOabXEUbBQr0w.png

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

1_SGGuu9I5qxFW7M69VoGXNA.png

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

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

0_b9ZHLsgBBdNHE8rr.png

相反,我们比较对象的特殊构造函数属性与我们自己的构造函数属性:

1_42ANjAXvNdwxWNRp9Jc-Bg.png

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

1_yiUMVTFpAh9N4vQDI1ckgQ.png

2. Symbol.iterator

我们接下来的“Hack”是 Symbol.iterator,可以完全改变循环在对象上的工作方式和条件。

记住这个:

0_u5sfP6qyG0Ff4rSS.png

我们之所以能够做到这一点,多亏了Symbol.iterator

1_lz51S_1lE1jYRYTz7xQ-eg.png

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

每当我们使用 for..of

1_BhceTDn2eJxcN7q6cmxHfg.png

这是在幕后发生的:

1_1BTNuytgRhTVHFWB__KmBg.png

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

1_AmqqlEPV5MaCU3rOTjh5oQ.png

0_7OFcKq4kh4ucS7W7.png

3. Symbol.toPrimitive

使用 Symbol.toPrimitive,我们很快就能从这个状态转变到:

0_Wv6Bt8P6FUwS_OUa.png

转变到

0_LcMiVEZYchKkgq6u (1).png

我们通过重写 Symbol.toPrimitive 实现了这一点:

1_n-BL163zHFNg-4ThcRr6DA.png

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

1_bn2cZzLT_JJLdcpLmD6bIg.png

甚至还有一个提示参数,可以使对象像数字、字符串或其他类型一样运行。

1_sI0MiBHRPwesEuv-J51AuA.png

4. Symbol.split

可以将你的自定义对象转换为字符串分隔符:

1_cn0oB6bpAddHaR1gFy19dg.png

5. Symbol.search

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

1_Eyvg0PIy86Y-gObCicyeMw.png

总结

以上就是关于Hack Javascript的五种方式