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

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

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

2bb5bbffe63de68ffd038d580eed4a73.png

4adae80614579be6bc47b27ab4028704.png

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

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

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

1. Symbol.hasInstance

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

121af027cd10e59ce17dc98234d0dbf6.png

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

929ce32a3b9d61f7c6178ef0256d48d6.png

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

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

1c127b7a211e7da1f56270545c4d235a.png

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

bd5e2130b82f9a2a74a38d5c4473ffb7.png

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

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

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

d1aaae1f5a5ed15f13adde737d318886.png

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

d36bfe58d639bb901ae37a73c62e8836.png

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

72d1d8f6ad02e2809f694923b7daef4a.png

2. Symbol.iterator

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

还记得这个吗:

e44c7f888667fb6c780fe68c28decdc2.png

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

da47b50e50bda9b228e04fb157029f36.png

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

每当我们使用for..of

f44044646ef6d515d9e77a8624696f1e.png

这在幕后发生:

5f0ca260f32e89389af6a6f8e08ec35d.png

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

93a55c4a2515074273e90b29796baffe.png

8c4e3954dab73783f95c2c28d813bdaa.png

3. Symbol.toPrimitive

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

5d5146e1efc6e6764ec491020215251a.png

变成这个:

2dbfa922ff848759715ec531a0eb67c2.png

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

1de62bd4d9dfb1b7ca2cc7437c54ec39.png

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

77918b7c34a24a1cdada4f320695a08c.png

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

eef5d45c195bb22ee6096b4a526d2b10.png

4. Symbol.split

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

b37474d33c94132f4e15554473a0c042.png

5. Symbol.search

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

bc7d595489d43c1035e7fe7005418297.png

最后的思考

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

最后:

CSS技巧与案例详解

vue2与vue3技巧合集

VueUse源码解读

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@大迁世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值