#ECMAScript 2021 (ES12) 中的 Symbol.species,实现自定义数据类型的扩展
##引言
在现代的软件开发中,自定义数据类型已经成为了必不可少的部分。然而,在JavaScript中,自定义数据类型的实现却一直比较困难。为了解决这个问题,ECMAScript在2015年引入了Symbol这一机制。Symbol机制带来了一种新的方式来创建内置类型中的属性,但是它仍然没有解决所有的问题。在ECMAScript 2021 (ES12)中,Symbol.species被引入,可以扩展自定义数据类型,今天我们使用这个特性来完成一个自定义数据类型的扩展。
##什么是Symbol.species
Symbol.species是Symbol的一个新属性,在ES6中引进。它是一个函数,用于创建派生对象的构造函数。在派生对象中,该函数用于创建该派生对象的实例。Symbol.species带来了用一个函数来指定一个类的派生对象的能力。
##Symbol.species的作用
Symbol.species的最大作用是扩展自定义的数据类型。我们可以使用Symbol.species来修改默认的实现,并且可以在派生对象中应用这个自定义的实现。我们可以提高代码的解耦和可复用性。
##Symbol.species 的示例
为了更好地理解Symbol.species的作用,我们来看一个具体的示例。以下代码是一个简单的自定义数据类型:
class CustomArray extends Array { // constructor } let customArray = new CustomArray(1, 2, 3); let mappedArray = customArray.map(x => x * 2); console.log(mappedArray instanceof CustomArray); // true
上面的代码是一个类CustomArray,它继承自内置类型Array。在这个例子中,我们创建了CustomArray的一个实例,然后调用了map方法将每个元素乘以2并返回一个新的CustomArray实例。然后我们检查这个新的实例是否是CustomArray的一个实例,结果是true。
然而,我们发现这个示例中的mappedArray并不是CustomArray类型,它是普通的Array类型。这是为什么呢?这是因为在调用map方法时,它创建了一个新的数组实例。如果我们想要更好的控制,我们应该让它返回CustomArray类型。
在使用Symbol.species之前,我们会这样做:
-- -------------------- ---- ------- ----- ----------- ------- ----- - ------ --- ------------------ - ------ ------ - - --- ----------- - --- -------------- -- --- --- ----------- - ----------------- -- - - --- ----------------------- ---------- ------------- -- -----
这次,我们在CustomArray中的[Symbol.species]中指定了一个新的构造函数Array。现在这个MappedArray的实例不是CustomArray的实例而是Array的实例。我们用一个构造函数替换了默认的构造函数来定义返回类型并发挥了Symbol.species的作用。
现在我们使用Symbol.species来实现一个与上面相同的示例:
-- -------------------- ---- ------- ----- ----------- ------- ----- - ------ --- ------------------ - ------ ------------ - - --- ----------- - --- -------------- -- --- --- ----------- - ----------------- -- - - --- ----------------------- ---------- ------------- -- ----
这次我们用CustomArray替换了默认的构造函数。在调用map方法后,返回的实例是CustomArray的实例。
##总结
在本文中,我们了解了Symbol.species的作用。我们通过使用Symbol.species来控制实例化对象的类型,从而对自定义数据类型进行了扩展。当我们需要扩展某个类时,我们应该始终考虑使用Symbol.species属性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e8867ef6b2d6eab34128ac