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

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

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

160316d89c623fa7aa7bcac26c70ca13.png

56430f15e1936fdcbcb66c24a884da62.png

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

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

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

1. Symbol.hasInstance

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

c92d12e33f62673d7930ad568cfc4d52.png

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

5e1a6fa5d3c4cda8cfa4980524afce6f.png

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

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

2dc456fb473485f8cd3d333e95f39ca6.png

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

969253f21fea589dff689d1454d8711f.png

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

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

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

62d88cc5bf1f0854013096d918d4bdaf.png

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

667560f0fabfcde906e64b58325b5f5f.png

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

b0a3f1d29723d13d8e3f8acca06265b6.png

2. Symbol.iterator

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

还记得这个吗:

27f3c5d0a8cd8b4abd3d4ac8c5c67b50.png

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

08ebee259fb45c95a911e199618faa0d.png

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

每当我们使用for..of

1fc117e6ae328a5304c9eca01dbd752b.png

这在幕后发生:

e896bf0dc04df3b59d349f626e36b845.png

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

ec5c6242242ae471d5b9fce9994e2d3b.png

99e4db7573e065091118cf4d8ecd2cc1.png

3. Symbol.toPrimitive

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

8142a24f19eca98b220c5bf79522c8e8.png

变成这个:

1b989da94988c7dabb6fe6f828e2339e.png

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

41a18437990b94dcf4882e9779e1f362.png

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

d479a317254fb7619a70f9eaf06861b8.png

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

001ad6ca5153c131fa4f11fdd8e58e6c.png

4. Symbol.split

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

2634e426eba0f3eca6eb2f1244a39b80.png

5. Symbol.search

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

d8f082b02c3af4607127e05d79118396.png

最后的思考

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

最后:

CSS技巧与案例详解

vue2与vue3技巧合集

VueUse源码解读

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值