ES7 中的 Symbol.species:如何使用和解决常见的 bug

· 约 5 分钟读完

简介

在 ES6 中,我们已经了解了 Symbol 类型,它是一种新的原生数据类型,用于创建独一无二的标识符。ES7 引入了 Symbol.species,它是 Symbol 的一个实例属性,用于指定创建派生对象的构造函数。

Symbol.species 是为了解决混合编程中程序的行为合理性问题而设计的。

使用 Symbol.species

在 ES6 中,我们通常利用数组的 map 和 filter 方法来生成新的数组。在某些场合下,我们希望生成的新数组与原数组是同一个类的实例,这时候,就可以使用 Symbol.species 属性。

举个栗子:

在上面的代码中,由于 map 方法生成的新数组是 Array 类的实例,所以新数组 b 的实例对象不是 MyArray。

现在,我们使用 Symbol.species 属性,让新数组 b 与原数组 a 保持同一种类。

我们在 MyArray 中定义了一个静态 getter 方法 Symbol.species,返回值为 Array。在 a.map() 方法执行时,由于 MyArray 中定义了 Symbol.species,新数组 b 就会由 Array 构造函数创建(而不是原生 Array 方法)。

解决常见的 bug

在许多情况下,我们都会需要扩展原生对象的原型方法。例如,我们可以将 String.prototype.padStart() 和 String.prototype.padEnd() 方法扩展到所有对象上。

这样就扩展了所有对象的原型。但是,这里存在一个问题。例如,如果在扩展原生的 String 对象上的方法时,会出现一个问题。

由于扩展了 Object.prototype 上的方法,导致了新的 String 对象没有了 padStart 方法。我们可以通过 Symbol.species 属性解决这个问题。

MyString 中定义了 padStart 和 padEnd 方法,通过这两种方法来生成一个新字符串,避免了在 Object.prototype 上扩展的问题。同时,根据 Symbol.species 的约定,MyString 类会生成一个新的字符串实例,而不是 Object 实例。

结语

Symbol.species 属性是 ES6 所引入的一种新的机制,用于解决由于混合编程而产生的行为不合理性问题。它定义了一个工厂方法,用于根据传入的参数生成对应的派生对象。在混合编程中,我们可以使用它来指定类的实例化过程,避免由于不同类之间的转换而导致的问题。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cfad4ee46428fe9eb79608