]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): track hasOwnProperty
authorEvan You <yyx990803@gmail.com>
Mon, 14 Nov 2022 09:17:35 +0000 (17:17 +0800)
committerEvan You <yyx990803@gmail.com>
Mon, 14 Nov 2022 09:17:35 +0000 (17:17 +0800)
fix #2619
close #2621

packages/reactivity/__tests__/effect.spec.ts
packages/reactivity/src/baseHandlers.ts

index a322c7209f4dc4dd90a4cce612424804812564bb..ed23b18446a87f8f73aa9e2e1864eb536253dc15 100644 (file)
@@ -964,5 +964,31 @@ describe('reactivity/effect', () => {
       m.set(key, 2)
       expect(fnSpy).toHaveBeenCalledTimes(2)
     })
+
+    test('should track hasOwnProperty', () => {
+      const obj: any = reactive({})
+      let has = false
+      const fnSpy = jest.fn()
+
+      effect(() => {
+        fnSpy()
+        has = obj.hasOwnProperty('foo')
+      })
+      expect(fnSpy).toHaveBeenCalledTimes(1)
+      expect(has).toBe(false)
+
+      obj.foo = 1
+      expect(fnSpy).toHaveBeenCalledTimes(2)
+      expect(has).toBe(true)
+
+      delete obj.foo
+      expect(fnSpy).toHaveBeenCalledTimes(3)
+      expect(has).toBe(false)
+
+      // should not trigger on unrelated key
+      obj.bar = 2
+      expect(fnSpy).toHaveBeenCalledTimes(3)
+      expect(has).toBe(false)
+    })
   })
 })
index dfff56f7fc5ed41b4360c62c5337c052d1fdf002..46240dba77c98463836c90958d95474e6d0f040d 100644 (file)
@@ -85,6 +85,13 @@ function createArrayInstrumentations() {
   return instrumentations
 }
 
+function hasOwnProperty(key: string) {
+  // @ts-ignore
+  const obj = toRaw(this)
+  track(obj, TrackOpTypes.HAS, key)
+  return obj.hasOwnProperty(key)
+}
+
 function createGetter(isReadonly = false, shallow = false) {
   return function get(target: Target, key: string | symbol, receiver: object) {
     if (key === ReactiveFlags.IS_REACTIVE) {
@@ -110,8 +117,13 @@ function createGetter(isReadonly = false, shallow = false) {
 
     const targetIsArray = isArray(target)
 
-    if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
-      return Reflect.get(arrayInstrumentations, key, receiver)
+    if (!isReadonly) {
+      if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
+        return Reflect.get(arrayInstrumentations, key, receiver)
+      }
+      if (key === 'hasOwnProperty') {
+        return hasOwnProperty
+      }
     }
 
     const res = Reflect.get(target, key, receiver)