From 83ed92608d81349e1cac2e481ed079e51a490b2b Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 26 Oct 2017 13:52:36 +0200 Subject: [PATCH] fix: $set should respect properties on prototype chain fix #6845 --- src/core/observer/index.js | 2 +- .../features/global-api/set-delete.spec.js | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/core/observer/index.js b/src/core/observer/index.js index 11de2d89..86a21f9e 100644 --- a/src/core/observer/index.js +++ b/src/core/observer/index.js @@ -196,7 +196,7 @@ export function set (target: Array | Object, key: any, val: any): any { target.splice(key, 1, val) return val } - if (hasOwn(target, key)) { + if (key in target && !(key in Object.prototype)) { target[key] = val return val } diff --git a/test/unit/features/global-api/set-delete.spec.js b/test/unit/features/global-api/set-delete.spec.js index d758422d..d1c7f3d8 100644 --- a/test/unit/features/global-api/set-delete.spec.js +++ b/test/unit/features/global-api/set-delete.spec.js @@ -80,6 +80,32 @@ describe('Global API: set/delete', () => { expect(vm.$el.innerHTML).toBe('

D

B

C

') }).then(done) }) + + // #6845 + it('should not overwrite properties on prototype chain', () => { + class Model { + constructor () { + this._bar = null + } + get bar () { + return this._bar + } + set bar (newvalue) { + this._bar = newvalue + } + } + + const vm = new Vue({ + data: { + data: new Model() + } + }) + + Vue.set(vm.data, 'bar', 123) + expect(vm.data.bar).toBe(123) + expect(vm.data.hasOwnProperty('bar')).toBe(false) + expect(vm.data._bar).toBe(123) + }) }) describe('Vue.delete', () => {