Skip to content

Commit 00ec76d

Browse files
committed
fix: ignore prototype methods when using setData on objects
1 parent 4bc3baa commit 00ec76d

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/utils.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,25 @@ export function mergeGlobalProperties(
7272
export const isObject = (obj: unknown): obj is Record<string, any> =>
7373
!!obj && typeof obj === 'object'
7474

75+
function isClass(obj: unknown) {
76+
if (!(obj instanceof Object)) return
77+
78+
const isCtorClass =
79+
obj.constructor && obj.constructor.toString().substring(0, 5) === 'class'
80+
81+
if (!('prototype' in obj)) {
82+
return isCtorClass
83+
}
84+
85+
const prototype = obj.prototype as any
86+
const isPrototypeCtorClass =
87+
prototype.constructor &&
88+
prototype.constructor.toString &&
89+
prototype.constructor.toString().substring(0, 5) === 'class'
90+
91+
return isCtorClass || isPrototypeCtorClass
92+
}
93+
7594
// https://stackoverflow.com/a/48218209
7695
export const mergeDeep = (
7796
target: Record<string, unknown>,
@@ -80,8 +99,13 @@ export const mergeDeep = (
8099
if (!isObject(target) || !isObject(source)) {
81100
return source
82101
}
102+
83103
Object.keys(source)
84-
.concat(Object.getOwnPropertyNames(Object.getPrototypeOf(source) ?? {}))
104+
.concat(
105+
isClass(source)
106+
? Object.getOwnPropertyNames(Object.getPrototypeOf(source) ?? {})
107+
: Object.getOwnPropertyNames(source)
108+
)
85109
.forEach((key) => {
86110
const targetValue = target[key]
87111
const sourceValue = source[key]

tests/setData.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,4 +246,33 @@ describe('setData', () => {
246246

247247
expect(wrapper.vm.getResult()).toStrictEqual(`test2: ${expectedResult}`)
248248
})
249+
250+
it('should be possible to replace a primitive value with another', async () => {
251+
const wrapper = mount(
252+
defineComponent({
253+
template: '<div />',
254+
data() {
255+
return {
256+
firstArray: [],
257+
secondArray: []
258+
}
259+
}
260+
})
261+
)
262+
263+
await wrapper.setData({
264+
firstArray: [],
265+
secondArray: []
266+
})
267+
268+
expect(wrapper.vm.$data).toStrictEqual({
269+
firstArray: [],
270+
secondArray: []
271+
})
272+
273+
expect(Object.keys(wrapper.vm.$data)).toStrictEqual([
274+
'firstArray',
275+
'secondArray'
276+
])
277+
})
249278
})

0 commit comments

Comments
 (0)