expect(original.indexOf(ref)).toBe(1)
})
})
+
+ describe('Array subclasses', () => {
+ class SubArray<T> extends Array<T> {
+ lastPushed: undefined | T
+ lastSearched: undefined | T
+
+ push(item: T) {
+ this.lastPushed = item
+ return super.push(item)
+ }
+
+ indexOf(searchElement: T, fromIndex?: number | undefined): number {
+ this.lastSearched = searchElement
+ return super.indexOf(searchElement, fromIndex)
+ }
+ }
+
+ test('calls correct mutation method on Array subclass', () => {
+ const subArray = new SubArray(4, 5, 6)
+ const observed = reactive(subArray)
+
+ subArray.push(7)
+ expect(subArray.lastPushed).toBe(7)
+ observed.push(9)
+ expect(observed.lastPushed).toBe(9)
+ })
+
+ test('calls correct identity-sensitive method on Array subclass', () => {
+ const subArray = new SubArray(4, 5, 6)
+ const observed = reactive(subArray)
+ let index
+
+ index = subArray.indexOf(4)
+ expect(index).toBe(0)
+ expect(subArray.lastSearched).toBe(4)
+
+ index = observed.indexOf(6)
+ expect(index).toBe(2)
+ expect(observed.lastSearched).toBe(6)
+ })
+ })
})
// instrument identity-sensitive Array methods to account for possible reactive
// values
;(['includes', 'indexOf', 'lastIndexOf'] as const).forEach(key => {
- const method = Array.prototype[key] as any
instrumentations[key] = function(this: unknown[], ...args: unknown[]) {
- const arr = toRaw(this)
+ const arr = toRaw(this) as any
for (let i = 0, l = this.length; i < l; i++) {
track(arr, TrackOpTypes.GET, i + '')
}
// we run the method using the original args first (which may be reactive)
- const res = method.apply(arr, args)
+ const res = arr[key](...args)
if (res === -1 || res === false) {
// if that didn't work, run it again using raw values.
- return method.apply(arr, args.map(toRaw))
+ return arr[key](...args.map(toRaw))
} else {
return res
}
// instrument length-altering mutation methods to avoid length being tracked
// which leads to infinite loops in some cases (#2137)
;(['push', 'pop', 'shift', 'unshift', 'splice'] as const).forEach(key => {
- const method = Array.prototype[key] as any
instrumentations[key] = function(this: unknown[], ...args: unknown[]) {
pauseTracking()
- const res = method.apply(this, args)
+ const res = (toRaw(this) as any)[key].apply(this, args)
resetTracking()
return res
}