Mocha+Babel替换数组扩展数组的class

Mocha+Babel replaces class that extends array by array

我用 Mocha 和 Babel 建立了一个项目。

如果我创建一个扩展 Array 的 class 并在实例上调用此 class 的方法,它在控制台中工作,但在使用 Mocha+Babel 的测试中失败:

似乎该实例被感知为Array的实例而不是扩展的class。

class:

class A extends Array {

    hello() {
        return "hi"
    }
}

测试:

import { expect, assert } from 'chai'
import { A } from 'a'

describe('A', () => {

    it('Should have a property', () => {        
        const result = new A();
        expect(result).to.have.property('hello')
    })

    it('Should be of the good type', () => {        
        const result = new A();
        expect(result).to.be.an.instanceOf(A)
    })


}
)

我得到的两个错误:

有什么办法可以解决这个问题?

我假设您正在使用 Babel 将其转换为 ES5。

Array 的行为与其他构造函数不太一样。在 ES5 中并没有真正等效的语法来执行此操作,因为在某种程度上它是 not even really possible in ES5。因此,Babel 生成的试图创建等效语法的内容不会像您期望的那样工作。

如果您查看生成的代码,您会发现这一行:

return _possibleConstructorReturn(this, (A.__proto__ || Object.getPrototypeOf(A)).apply(this, arguments));

此时,A.__proto__ 将是 Array,并且构造函数没有参数,因此调用 Array.apply(this, []) 并将结果传递给 call _possibleConstructorReturn.

的参数

_possibleConstructorReturn 中,您会发现这一行:

return call && (typeof call === "object" || typeof call === "function") ? call : self; }

在大多数情况下,在构造函数上调用 apply(在没有 new 的情况下调用它)将 return 未定义。因此,此函数将 return self 参数,即来自 A 构造函数调用的 this

但是,

Array 的行为与普通构造函数不同。如果你在没有 new 的情况下调用它,它仍然是 return 一个数组。因此,从 A 构造函数中得到的只是一个普通的旧数组。

可能有解决方法,但 Babel 不支持任何方法。老实说,如果你需要你的代码在 ES5 中工作,你可能不应该尝试像这样扩展数组。 :\

通常的替代方法是编写一个简单的 class,将数组存储为 属性,并为您需要的数组操作提供包装方法。说一个 get 方法来代替方括号 属性 访问,一个 push 只是在包装数组上调用 push