Я организовал проект с Моккой и Вавилоном.
Если я создам класс, который расширяет Array и вызывает метод этого класса в экземпляре, он работает в консоли, но не проходит тест с Mocha + Babel:
Кажется, что экземпляр воспринимается как экземпляр массива вместо расширенного класса.
Класс:
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 на самом деле нет эквивалентного синтаксиса, поскольку в 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
, он все равно вернет массив. Итак, что вы получаете от своего конструктора A
- это просто старый массив.
Могут быть способы обойти это, но Вавилон не поддерживает. Если честно, если вам нужен ваш код для работы в ES5, вы, вероятно, не должны пытаться распространять такие массивы. :\
То, что часто работает в качестве альтернативы, - это написать простой класс, в котором хранится массив как свойство, с методами обертки для операций массива, в которых вы нуждаетесь. Скажем, метод get
используется вместо доступа к свойствам квадратных скобок, push
которое просто вызывает push
на завернутый массив.