Mocha + Babel替换了按数组扩展数组的类

时间:2018-06-18 21:31:39

标签: javascript ecmascript-6 mocha babeljs

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

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

似乎该实例被视为Array的实例,而不是扩展类。

班级:

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)
    })


}
)

我得到的两个错误:

  • AssertionError:expect []拥有属性'hello'
  • AssertionError:expected []是A
  • 的一个实例

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

1 个答案:

答案 0 :(得分:1)

我假设您正在使用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的情况下调用)将返回undefined。因此,此函数将返回self参数,该参数是this构造函数调用中的A

Array的行为不像普通的构造函数。如果您在不使用new的情况下调用它,它将仍然返回一个Array。因此,您从A构造函数中得到的只是一个普通的旧数组。

可能有一些解决方法,但是Babel不支持任何方法。老实说,如果您需要代码在ES5中运行,则可能不应该尝试扩展此类数组。 :\

通常作为替代方法的是编写一个简单的类,该类将数组存储为属性,并具有用于所需数组操作的包装器方法。说一个get方法来代替方括号属性访问,而一个push只需在包装好的数组上调用push