refactor: extract hasOwn helper

This commit is contained in:
Evan You 2019-09-05 20:48:14 -04:00
parent 7eed0df3c2
commit 891f21b010
5 changed files with 23 additions and 20 deletions

View File

@ -2,11 +2,9 @@ import { reactive, readonly, toRaw } from './reactive'
import { OperationTypes } from './operations' import { OperationTypes } from './operations'
import { track, trigger } from './effect' import { track, trigger } from './effect'
import { LOCKED } from './lock' import { LOCKED } from './lock'
import { isObject } from '@vue/shared' import { isObject, hasOwn } from '@vue/shared'
import { isRef } from './ref' import { isRef } from './ref'
const hasOwnProperty = Object.prototype.hasOwnProperty
const builtInSymbols = new Set( const builtInSymbols = new Set(
Object.getOwnPropertyNames(Symbol) Object.getOwnPropertyNames(Symbol)
.map(key => (Symbol as any)[key]) .map(key => (Symbol as any)[key])
@ -40,7 +38,7 @@ function set(
receiver: any receiver: any
): boolean { ): boolean {
value = toRaw(value) value = toRaw(value)
const hadKey = hasOwnProperty.call(target, key) const hadKey = hasOwn(target, key)
const oldValue = target[key] const oldValue = target[key]
if (isRef(oldValue) && !isRef(value)) { if (isRef(oldValue) && !isRef(value)) {
oldValue.value = value oldValue.value = value
@ -69,7 +67,7 @@ function set(
} }
function deleteProperty(target: any, key: string | symbol): boolean { function deleteProperty(target: any, key: string | symbol): boolean {
const hadKey = hasOwnProperty.call(target, key) const hadKey = hasOwn(target, key)
const oldValue = target[key] const oldValue = target[key]
const result = Reflect.deleteProperty(target, key) const result = Reflect.deleteProperty(target, key)
if (hadKey) { if (hadKey) {

View File

@ -2,7 +2,7 @@ import { toRaw, reactive, readonly } from './reactive'
import { track, trigger } from './effect' import { track, trigger } from './effect'
import { OperationTypes } from './operations' import { OperationTypes } from './operations'
import { LOCKED } from './lock' import { LOCKED } from './lock'
import { isObject, capitalize } from '@vue/shared' import { isObject, capitalize, hasOwn } from '@vue/shared'
const toReactive = (value: any) => (isObject(value) ? reactive(value) : value) const toReactive = (value: any) => (isObject(value) ? reactive(value) : value)
const toReadonly = (value: any) => (isObject(value) ? readonly(value) : value) const toReadonly = (value: any) => (isObject(value) ? readonly(value) : value)
@ -222,9 +222,7 @@ function createInstrumentationGetter(instrumentations: any) {
receiver: any receiver: any
) { ) {
target = target =
instrumentations.hasOwnProperty(key) && key in target hasOwn(instrumentations, key) && key in target ? instrumentations : target
? instrumentations
: target
return Reflect.get(target, key, receiver) return Reflect.get(target, key, receiver)
} }
} }

View File

@ -8,7 +8,8 @@ import {
isFunction, isFunction,
isArray, isArray,
isObject, isObject,
isReservedProp isReservedProp,
hasOwn
} from '@vue/shared' } from '@vue/shared'
import { warn } from './warning' import { warn } from './warning'
import { Data, ComponentInstance } from './component' import { Data, ComponentInstance } from './component'
@ -123,7 +124,7 @@ export function resolveProps(
if (isReservedProp(key)) continue if (isReservedProp(key)) continue
// any non-declared data are put into a separate `attrs` object // any non-declared data are put into a separate `attrs` object
// for spreading // for spreading
if (hasDeclaredProps && !options.hasOwnProperty(key)) { if (hasDeclaredProps && !hasOwn(options, key)) {
;(attrs || (attrs = {}))[key] = rawProps[key] ;(attrs || (attrs = {}))[key] = rawProps[key]
} else { } else {
setProp(key, rawProps[key]) setProp(key, rawProps[key])
@ -135,8 +136,8 @@ export function resolveProps(
for (const key in options) { for (const key in options) {
let opt = options[key] let opt = options[key]
if (opt == null) continue if (opt == null) continue
const isAbsent = !props.hasOwnProperty(key) const isAbsent = !hasOwn(props, key)
const hasDefault = opt.hasOwnProperty('default') const hasDefault = hasOwn(opt, 'default')
const currentValue = props[key] const currentValue = props[key]
// default values // default values
if (hasDefault && currentValue === undefined) { if (hasDefault && currentValue === undefined) {
@ -173,7 +174,7 @@ export function resolveProps(
) { ) {
const rawInitialProps = toRaw(propsProxy) const rawInitialProps = toRaw(propsProxy)
for (const key in rawInitialProps) { for (const key in rawInitialProps) {
if (!props.hasOwnProperty(key)) { if (!hasOwn(props, key)) {
delete propsProxy[key] delete propsProxy[key]
} }
} }

View File

@ -1,16 +1,16 @@
import { ComponentInstance } from './component' import { ComponentInstance } from './component'
import { nextTick } from './scheduler' import { nextTick } from './scheduler'
import { instanceWatch } from './apiWatch' import { instanceWatch } from './apiWatch'
import { EMPTY_OBJ } from '@vue/shared' import { EMPTY_OBJ, hasOwn } from '@vue/shared'
export const RenderProxyHandlers = { export const RenderProxyHandlers = {
get(target: ComponentInstance, key: string) { get(target: ComponentInstance, key: string) {
const { renderContext, data, props, propsProxy } = target const { renderContext, data, props, propsProxy } = target
if (data !== EMPTY_OBJ && data.hasOwnProperty(key)) { if (data !== EMPTY_OBJ && hasOwn(data, key)) {
return data[key] return data[key]
} else if (renderContext.hasOwnProperty(key)) { } else if (hasOwn(renderContext, key)) {
return renderContext[key] return renderContext[key]
} else if (props.hasOwnProperty(key)) { } else if (hasOwn(props, key)) {
// return the value from propsProxy for ref unwrapping and readonly // return the value from propsProxy for ref unwrapping and readonly
return (propsProxy as any)[key] return (propsProxy as any)[key]
} else { } else {
@ -53,9 +53,9 @@ export const RenderProxyHandlers = {
}, },
set(target: ComponentInstance, key: string, value: any): boolean { set(target: ComponentInstance, key: string, value: any): boolean {
const { data, renderContext } = target const { data, renderContext } = target
if (data !== EMPTY_OBJ && data.hasOwnProperty(key)) { if (data !== EMPTY_OBJ && hasOwn(data, key)) {
data[key] = value data[key] = value
} else if (renderContext.hasOwnProperty(key)) { } else if (hasOwn(renderContext, key)) {
renderContext[key] = value renderContext[key] = value
} else if (key[0] === '$' && key.slice(1) in target) { } else if (key[0] === '$' && key.slice(1) in target) {
// TODO warn attempt of mutating public property // TODO warn attempt of mutating public property

View File

@ -15,6 +15,12 @@ export const extend = <T extends object, U extends object>(
return a as any return a as any
} }
const hasOwnProperty = Object.prototype.hasOwnProperty
export const hasOwn = (
val: object,
key: string | symbol
): key is keyof typeof val => hasOwnProperty.call(val, key)
export const isArray = Array.isArray export const isArray = Array.isArray
export const isFunction = (val: any): val is Function => export const isFunction = (val: any): val is Function =>
typeof val === 'function' typeof val === 'function'