ES9 中的 Symbol.species 属性详解

阅读时长 5 分钟读完

前言

Symbol.species 是 ES9 引入的一个新的 Symbol 类型属性。它是作为类的属性而存在的,其作用是定义一个创建衍生对象时要调用的默认构造函数。本文将详细探讨 Symbol.species 和它在前端开发中的应用。

Symbol.species 的用途

在面向对象的编程中,常常需要在一个类的基础上扩展出新的子类,这时使用继承是一个常见的选择。继承可以让子类拥有父类的所有属性和方法,而且可以根据需要新增一些特定的属性和方法。ES6 引入了类的概念,让面向对象的编程更加规范化与便捷化,子类可以通过 extends 关键字继承父类。

继承的过程中,当子类继承自父类的实例时,就需要创建一个新的实例。为了创建这个新的实例,子类需要调用父类的构造函数。这个构造函数称为默认构造函数。在 ES6 中,类的继承是通过 extends 关键字和 super 关键字来实现的,如下所示:

-- -------------------- ---- -------
----- ------ -
  ----------------- -
    --------- - -----
  -
  ------- -
    ------------------------- ----- - ---------
  -
-

----- --- ------- ------ -
  ----------------- -
    ------------
  -
  ------- -
    ------------------------- ---------
  -
-

--- - - --- --------------
---------- -- ------ ------
展开代码

在这个例子中,Dog 类继承自 Animal 类。在 Dog 的构造函数中,使用 super 关键字调用 Animal 的构造函数,并向其传递参数。这是因为子类必须在构造函数中调用父类的构造函数来实现继承。通过 extends 和 super,Dog 继承了 Animal 的属性和方法,同时还可以添加自己的属性和方法。

在上述例子基础上,可以再创建一个 Cat 类。对于 Cat 和 Dog 两个类,它们都继承自 Animal,但是它们的 speak 方法分别输出不同的内容。这是因为 speak 方法在子类中被覆盖了。但是,这里出现了一个问题:子类继承自父类后,在进行某些操作(如复制、深拷贝等)时,子类实例的类型可能被改变。比如,使用 slice 方法复制一个 Dog 实例 d1 生成一个新的实例 d2,那么 d2的类型就不再是 Dog,而是 Animal。这是因为 slice 方法在创建一个新的数组时,将继承自原数组的类信息丢掉了。代码如下:

为了解决这个问题,ES9 引入了 Symbol.species 属性。它可以用来指定在衍生对象中创建新一代实例时要使用的构造函数。衍生对象继承自原型对象,且在创建衍生对象时会调用原型对象的 Symbol.species 方法(如果原型对象有这个方法的话),从而获得在衍生对象中创建新实例的默认构造函数。这样就保证了生成的实例的类型与原实例的类型相同。还是以上述例子为基础,我们可以通过指定 Dog 和 Cat 的 Symbol.species 属性为自己的构造函数来解决这个问题,代码如下:

-- -------------------- ---- -------
----- ------ -
  ----------------- -
    --------- - -----
  -
  ------- -
    ------------------------- ----- - ---------
  -
  ------ --- ------------------ -
    ------ -----
  -
-

----- --- ------- ------ -
  ----------------- -
    ------------
  -
  ------- -
    ------------------------- ---------
  -
  ------ --- ------------------ -
    ------ -----
  -
-

----- --- ------- ------ -
  ----------------- -
    ------------
  -
  ------- -
    ------------------------- ---------
  -
  ------ --- ------------------ -
    ------ -----
  -
-

--- -- - --- --------------
--- -- - -----------
-------------- ---------- -------- -- -----
-------------- ---------- ----- -- ----

--- -- - --- --------------
--- -- - -----------
-------------- ---------- -------- -- -----
-------------- ---------- ----- -- ----
展开代码

在上面的代码中,为 Animal、Dog 和 Cat 类都定义了 Symbol.species 属性。它们的值都是指向自身的类构造函数,表示在衍生对象中创建新实例时使用自身的构造函数。这样,在对 Dog 的实例 d1 进行 slice 操作后,生成的新实例 d2 类型是 Dog。对 Cat 的实例也是如此。类似的,当在其它操作中需要创建新实例时,也会调用 Symbol.species 方法并基于其返回值来确定默认构造函数。

小结

Symbol.species 属性是 ES9 引入的一个新的 Symbol 类型属性,它是作为类的属性而存在的,其作用是定义一个创建衍生对象时要调用的默认构造函数。在子类继承自父类时,指定 Symbol.species 属性为自身的类构造函数,可以保证生成的实例类型与原实例类型相同,在进行某些操作时不会丢失类信息。亲手实践一遍,理解它的作用和用法也是必要的。

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

纠错
反馈

纠错反馈