我与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)
})
}
)
我得到的两个错误:
有什么方法可以解决这个问题吗?
答案 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
。