首页 > 解决方案 > Mocha+Babel 替换了逐个数组扩展的类

问题描述

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


}
)

我得到的两个错误:

有什么办法可以解决吗?

标签: javascriptecmascript-6mocha.jsbabeljs

解决方案


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

Array与其他构造函数的行为不太一样。在 ES5 中并没有真正的等效语法,因为在某种程度上它在 ES5 中甚至是不可能的。因此,Babel 为尝试创建等效语法而生成的内容不会像您期望的那样工作。

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

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

此时,A.__proto__will be Array,并且构造函数没有给出任何参数,所以 this 正在调用Array.apply(this, [])并将结果传递给 的call参数_possibleConstructorReturn

_possibleConstructorReturn中,您会发现这一行:

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

在大多数情况下,调用apply构造函数(在没有 的情况下调用它new)将返回 undefined。因此,此函数将返回self参数,该参数this来自A构造函数调用。

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

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

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


推荐阅读