Page 248 - 你不知道的JavaScript(下卷)
P. 248

要在一个函数上设定 @@hasInstance,必须使用 Object.defineProperty(..),
                            因为 Function.prototype 上默认的那一个是 writable: false(不可写的)。
                            参见本系列《你不知道的 JavaScript(上卷)》第二部分获取更多信息。



                 7.3.3 Symbol.species
                 在 3.4 节中,我们介绍了符号 @@species,这个符号控制要生成新实例时,类的内置方法使
                 用哪一个构造器。

                 最常见的例子是,在创建 Array 的子类并想要定义继承的方法(比如 slice(..))时使用
                 哪一个构造器(是 Array(..) 还是自定义的子类)。默认情况下,调用 Array 子类实例上的
                 slice(..) 会创建这个子类的新实例,坦白说这很可能就是你想要的。

                 但是,你可以通过覆盖一个类的默认 @@species 定义来进行元编程:

                     class Cool {
                         // 把@@species推迟到子类
                         static get [Symbol.species]() { return this; }

                         again() {
                             return new this.constructor[Symbol.species]();
                         }
                     }

                     class Fun extends Cool {}

                     class Awesome extends Cool {
                         // 强制指定@@species为父构造器
                         static get [Symbol.species]() { return Cool; }
                     }

                     var a = new Fun(),
                         b = new Awesome(),
                         c = a.again(),
                         d = b.again();

                     c instanceof Fun;       // true
                     d instanceof Awesome;   // false
                     d instanceof Cool;      // true

                 就像前面代码中 Cool 的定义那样,内置原生构造器上 Symbol.species 的默认行为是
                 return this。在用户类上没有默认值,但是就像展示的那样,这个行为特性很容易模拟。

                 如果需要定义生成新实例的方法,使用 new this.constructor[Symbol.species](..) 模式
                 元编程,而不要硬编码 new this.constructor(..) 或 new XYZ(..)。然后继承类就能够自定
                 义 Symbol.species 来控制由哪个构造器产生这些实例。



                                                                               元编程   |   225

                                图灵社区会员 avilang(1985945885@qq.com) 专享 尊重版权
   243   244   245   246   247   248   249   250   251   252   253