Przeglądaj źródła

fix: ocurred error in 'set' and 'delete' utility functions

kazuya kawaguchi 10 lat temu
rodzic
commit
2b79ebe418

+ 1 - 1
src/compiler/compile-props.js

@@ -185,7 +185,7 @@ function makePropsLinkFn (props) {
 
 function getDefault (vm, options) {
   // no default, return undefined
-  if (!options.hasOwnProperty('default')) {
+  if (!_.hasOwn(options, 'default')) {
     // absent boolean value defaults to false
     return options.type === Boolean
       ? false

+ 1 - 1
src/directives/internal/class.js

@@ -67,5 +67,5 @@ function stringToObject (value) {
 function contains (value, key) {
   return _.isArray(value)
     ? value.indexOf(key) > -1
-    : value.hasOwnProperty(key)
+    : _.hasOwn(value, key)
 }

+ 1 - 1
src/directives/public/el.js

@@ -11,7 +11,7 @@ module.exports = {
     }
     var id = this.id = _.camelize(this.arg)
     var refs = (this._scope || this.vm).$els
-    if (refs.hasOwnProperty(id)) {
+    if (_.hasOwn(refs, id)) {
       refs[id] = this.el
     } else {
       _.defineReactive(refs, id, this.el)

+ 4 - 4
src/directives/public/for.js

@@ -87,8 +87,8 @@ module.exports = {
     var item = data[0]
     var convertedFromObject = this.fromObject =
       isObject(item) &&
-      item.hasOwnProperty('$key') &&
-      item.hasOwnProperty('$value')
+      _.hasOwn(item, '$key') &&
+      _.hasOwn(item, '$value')
 
     var trackByKey = this.params.trackBy
     var oldFrags = this.frags
@@ -366,7 +366,7 @@ module.exports = {
       }
     } else {
       id = this.id
-      if (value.hasOwnProperty(id)) {
+      if (_.hasOwn(value, id)) {
         if (value[id] === null) {
           value[id] = frag
         } else {
@@ -423,7 +423,7 @@ module.exports = {
     var index = scope.$index
     // fix #948: avoid accidentally fall through to
     // a parent repeater which happens to have $key.
-    var key = scope.hasOwnProperty('$key') && scope.$key
+    var key = _.hasOwn(scope, '$key') && scope.$key
     var primitive = !isObject(value)
     if (trackByKey || key || primitive) {
       var id = trackByKey

+ 3 - 3
src/instance/state.js

@@ -54,14 +54,14 @@ exports._initData = function () {
     this._data = optionsData
     for (var prop in propsData) {
       if (process.env.NODE_ENV !== 'production' &&
-          optionsData.hasOwnProperty(prop)) {
+          _.hasOwn(optionsData, prop)) {
         _.warn(
           'Data field "' + prop + '" is already defined ' +
           'as a prop. Use prop default value instead.'
         )
       }
       if (this._props[prop].raw !== null ||
-          !optionsData.hasOwnProperty(prop)) {
+          !_.hasOwn(optionsData, prop)) {
         _.set(optionsData, prop, propsData[prop])
       }
     }
@@ -105,7 +105,7 @@ exports._setData = function (newData) {
   i = keys.length
   while (i--) {
     key = keys[i]
-    if (!this.hasOwnProperty(key)) {
+    if (!_.hasOwn(this, key)) {
       // new property
       this._proxy(key)
     }

+ 1 - 1
src/observer/index.js

@@ -48,7 +48,7 @@ Observer.create = function (value, vm) {
   }
   var ob
   if (
-    Object.prototype.hasOwnProperty.call(value, '__ob__') &&
+    _.hasOwn(value, '__ob__') &&
     value.__ob__ instanceof Observer
   ) {
     ob = value.__ob__

+ 14 - 2
src/util/lang.js

@@ -10,7 +10,7 @@
  */
 
 exports.set = function set (obj, key, val) {
-  if (obj.hasOwnProperty(key)) {
+  if (exports.hasOwn(obj, key)) {
     obj[key] = val
     return
   }
@@ -43,7 +43,7 @@ exports.set = function set (obj, key, val) {
  */
 
 exports.delete = function (obj, key) {
-  if (!obj.hasOwnProperty(key)) {
+  if (!exports.hasOwn(obj, key)) {
     return
   }
   delete obj[key]
@@ -62,6 +62,18 @@ exports.delete = function (obj, key) {
   }
 }
 
+var hasOwn = Object.prototype.hasOwnProperty
+/**
+ * Check whether the object has the property.
+ *
+ * @param {Object} obj
+ * @param {String} key
+ * @return {Boolean}
+ */
+exports.hasOwn = function (obj, key) {
+  return hasOwn.call(obj, key)
+}
+
 /**
  * Check if an expression is a literal value.
  *

+ 2 - 2
src/util/options.js

@@ -25,7 +25,7 @@ function mergeData (to, from) {
   for (key in from) {
     toVal = to[key]
     fromVal = from[key]
-    if (!to.hasOwnProperty(key)) {
+    if (!_.hasOwn(to, key)) {
       _.set(to, key, fromVal)
     } else if (_.isObject(toVal) && _.isObject(fromVal)) {
       mergeData(toVal, fromVal)
@@ -326,7 +326,7 @@ exports.mergeOptions = function merge (parent, child, vm) {
     mergeField(key)
   }
   for (key in child) {
-    if (!(parent.hasOwnProperty(key))) {
+    if (!(_.hasOwn(parent, key))) {
       mergeField(key)
     }
   }

+ 2 - 2
test/unit/specs/api/data_spec.js

@@ -72,8 +72,8 @@ describe('Data API', function () {
   it('$delete', function () {
     vm._digest = jasmine.createSpy()
     vm.$delete('a')
-    expect(vm.hasOwnProperty('a')).toBe(false)
-    expect(vm._data.hasOwnProperty('a')).toBe(false)
+    expect(_.hasOwn(vm, 'a')).toBe(false)
+    expect(_.hasOwn(vm._data, 'a')).toBe(false)
     expect(vm._digest).toHaveBeenCalled()
     // reserved key should not be deleted
     vm.$delete('_data')

+ 3 - 2
test/unit/specs/instance/state_spec.js

@@ -1,4 +1,5 @@
 var Vue = require('../../../../src/vue')
+var _ = require('../../../../src/util')
 
 describe('Instance state initialization', function () {
 
@@ -38,7 +39,7 @@ describe('Instance state initialization', function () {
         el: document.createElement('div'),
         props: ['c']
       })
-      expect(vm.hasOwnProperty('c')).toBe(true)
+      expect(_.hasOwn(vm, 'c')).toBe(true)
     })
 
     it('should use default prop value if prop not provided', function () {
@@ -98,7 +99,7 @@ describe('Instance state initialization', function () {
       // proxy new key
       expect(vm.b).toBe(2)
       // unproxy old key that's no longer present
-      expect(vm.hasOwnProperty('a')).toBe(false)
+      expect(_.hasOwn(vm, 'a')).toBe(false)
     })
   })
 

+ 14 - 2
test/unit/specs/observer/observer_spec.js

@@ -282,7 +282,7 @@ describe('Observer', function () {
     expect(obj.b).toBe(2)
     expect(dep.notify.calls.count()).toBe(1)
     _.delete(obj, 'a')
-    expect(obj.hasOwnProperty('a')).toBe(false)
+    expect(_.hasOwn(obj, 'a')).toBe(false)
     expect(dep.notify.calls.count()).toBe(2)
     // set existing key, should be a plain set and not
     // trigger own ob's notify
@@ -299,7 +299,19 @@ describe('Observer', function () {
     // should work on non-observed objects
     var obj2 = { a: 1 }
     _.delete(obj2, 'a')
-    expect(obj2.hasOwnProperty('a')).toBe(false)
+    expect(_.hasOwn(obj2, 'a')).toBe(false)
+    // should work on Object.create(null)
+    var obj3 = Object.create(null)
+    obj3.a = 1
+    var ob3 = Observer.create(obj3)
+    var dep3 = ob3.dep
+    spyOn(dep3, 'notify')
+    _.set(obj3, 'b', 2)
+    expect(obj3.b).toBe(2)
+    expect(dep3.notify.calls.count()).toBe(1)
+    _.delete(obj3, 'a')
+    expect(_.hasOwn(obj3, 'a')).toBe(false)
+    expect(dep3.notify.calls.count()).toBe(2)
   })
 
   it('observing array mutation', function () {

+ 2 - 1
test/unit/specs/parsers/path_spec.js

@@ -1,4 +1,5 @@
 var Path = require('../../../../src/parsers/path')
+var _ = require('../../../../src/util')
 
 function assertPath (str, expected) {
   var path = Path.parse(str)
@@ -134,7 +135,7 @@ describe('Path Parser', function () {
     var target = Object.create(parent)
     var res = Path.set(target, 'a.b.c', 123)
     expect(res).toBe(true)
-    expect(target.hasOwnProperty('a')).toBe(false)
+    expect(_.hasOwn(target, 'a')).toBe(false)
     expect(parent.a.b.c).toBe(123)
   })
 

+ 8 - 0
test/unit/specs/util/lang_spec.js

@@ -2,6 +2,14 @@ var _ = require('../../../../src/util')
 
 describe('Util - Language Enhancement', function () {
 
+  it('hasOwn', function () {
+    var obj1 = { a: 1 }
+    expect(_.hasOwn(obj1, 'a')).toBe(true)
+    var obj2 = Object.create(null)
+    obj2.a = 2
+    expect(_.hasOwn(obj2, 'a')).toBe(true)
+  })
+
   it('isLiteral', function () {
     expect(_.isLiteral('123')).toBe(true)
     expect(_.isLiteral('12.3')).toBe(true)