解决使用 ES7 中的 Symbol.species 存在的对象继承问题

阅读时长 4 分钟读完

ES7 中新增的 Symbol.species 属性带来了许多优秀的技术解决方案,然而在对象继承中,为了避免出现类型混乱和错误的后果,使用 Symbol.species 也存在一定的问题。本文将详细讲解 Symbol.species 在对象继承中遇到的问题以及解决方案,并且提供相应的示例代码和学习指导意义。

问题描述

我们首先来看一个简单的例子:

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

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

上述代码中,MyArray 是一个继承自 Array 的自定义类,我们使用 Symbol.species 设置了类方法的返回值,从而期望生成的结果类型是 Array,但是我们在运行上述代码后,输出结果为 false 和 true。

我们知道,使用 Symbol.species 之后,应该实现方式如下:

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

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

通过这个例子可以看出,我们在使用 Symbol.species 时,这个属性只是用来告诉 JavaScript 引擎该返回什么类型的值,而并不会影响对象的类型,这就带来了一定的问题。

当我们期望使用 Symbol.species 来生成某个类型的实例时,实际上返回的还是继承类的实例。这种带来的类型转换混淆问题,可能会对程序的运行产生一些不可预期的后果。

解决方案

使用 Symbol.species 的目的是为了避免对象继承链中出现类型错误,但是它提供的解决方法可能会导致不必要的混淆和类型转换问题,如何解决这个问题呢?

我们可以使用 Object.create() 方法,以避免使用 Symbol.species 时存在的类型混淆问题。

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

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

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

上述代码中,我们在实现 filter() 方法时,使用了 Object.create() 方法来创建一个实例。我们同时又将 Symbol.species 属性作为对象的构造器,从而在继承顺序中的确使用了 Symbol.species 来生成一个新的对象。这样看来,就成功避免了使用 Symbol.species 时存在的类型混淆问题。

学习意义

ES7 中的 Symbol.species 没有实现我们期望的目标,但在实际开发中,了解该属性在对象继承中的用途和存在的问题是十分重要的。我们也可以从解决方案中学到许多在实际开发中避免类型混淆和不必要类型转换的技巧和思路,提高自己的代码的健壮性和可维护性。

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

纠错
反馈

纠错反馈