在 ECMAScript 2021 (ES12) 中, Well-Known Symbols 提供了一种新的机制来重载操作符。这个新特性可以让我们更加灵活和高效地定义自己的对象类型,以及增强对象的语义。
Well-Known Symbols 是什么?
Well-Known Symbols 是 ECMAScript 中的一组特殊符号,它们具有特定的含义,可以被用来覆盖一些内置行为。比如 Symbol.iterator 可以被用来重载对象的迭代器,Symbol.toStringTag 可以被用来定义一个对象的字符串表示形式。
在 ES6 中,第一批特殊符号被引入了标准库,包括 Symbol.iterator、Symbol.hasInstance、Symbol.match 等。而在后续的版本中,每一版都会引入新的 Well-Known Symbols。
为什么需要 Well-Known Symbols?
在 ES6 以前的版本中,对象属性都是基于字符串命名的。这种命名方式的局限性就在于,如果我们要手动重写一个对象的某个行为(比如迭代器),我们只能使用对象的方法,这样能带来一定的限制和效率问题。
而 Well-Known Symbols 提供了一种全新的方式,让我们可以像内置类型一样对自己定义的对象类型进行操作符的重载。这样,我们就可以将自己定义的对象类型和内置类型一样进行扩展,并且保证行为的一致性和正确性。
如何使用 Well-Known Symbols?
使用 Well-Known Symbols 就是将一个指定的符号作为对象的属性名,然后将其绑定到一个函数上,这个函数就可以实现指定符号所代表的行为。一般来说,这个函数应该返回一个适当的值,比如一个迭代器、一个字符串、一个布尔值等。
接下来,我们以实现一个数组对象为例,来讲解如何使用 Well-Known Symbols。
实现一个数组对象
首先,我们需要给数组对象定义一个符号。这个符号的名字可以是任意字符串,但如果想要使用 Well-Known Symbols 实现行为的重载,字符串必须和标准库中定义的符号完全一致。我们这里使用 Symbol.iterator 作为符号名。
const myArray = { [Symbol.iterator]: function* () { } };
接下来,我们需要将一个函数绑定到这个符号上,用来实现迭代器的行为。这个函数需要返回一个生成器对象,用来生成迭代器的值。这里我们简单地返回一个迭代器对象,用来生成 10 个随机数。
const myArray = { [Symbol.iterator]: function *() { for (let i = 0; i < 10; i++) { yield Math.random(); } } };
最后,我们可以使用 for-of 循环来遍历我们自己定义的数组对象。因为我们已经实现了迭代器的行为,所以 for-of 循环内部就会自动调用我们绑定的函数,来生成迭代值。
for (const value of myArray) { console.log(value); }
自定义字符串表示形式
除了可以实现迭代器之外,还可以使用 Well-Known Symbols 来定制化对象的字符串表示形式。这可以通过重载 Symbol.toStringTag 操作符来实现。我们可以将其绑定到一个自定义的函数上,这个函数返回希望对象表示为的字符串形式。比如:
-- -------------------- ---- ------- ----- -------- - - --------------------- ----------------- ----- ----- ---- --- --------- ---------- - ------ ----------------------------- - -- ------------------------------------------------------ -- -- ------- --------------- --------------------------------- -- -- ----- --
注意,如果没有定义 Symbol.toStringTag,对象的 toString() 方法会返回 Object 构造函数名,如下所示。
-- -------------------- ---- ------- ----- -------- - - ----- ----- ---- --- --------- ---------- - ------ ----------------------------- - -- ------------------------------------------------------ -- -- ------- ------- --------------------------------- -- -- ----- --
总结
通过使用 Well-Known Symbols,我们可以很好地扩展自定义的对象类型,通过重写一些操作符,增强对象的语义和可用性。同时, Well-Known Symbols 还可以让我们更加灵活和高效地实现自己的对象类型,提高代码的可读性和可扩展性。在实现自定义的对象类型时,我们应该优先考虑使用 Well-Known Symbols 的方式来进行操作符的重载。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64cdc1231519ea946c1901f0