text: /* not type checking this file because flow doesn't play well with Proxy */
  
  import config from 'core/config'
  import { warn, makeMap, isNative } from '../util/index'
  
  let initProxy
  
  if (process.env.NODE_ENV !== 'production') {
    const allowedGlobals = makeMap(
      'Infinity,undefined,NaN,isFinite,isNaN,' +
      'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
      'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
      'require' // for Webpack/Browserify
    )
  
    const warnNonPresent = (target, key) => {
      warn(
        `Property or method "${key}" is not defined on the instance but ` +
        'referenced during render. Make sure that this property is reactive, ' +
        'either in the data option, or for class-based components, by ' +
        'initializing the property. ' +
        'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
        target
      )
    }
  
    const warnReservedPrefix = (target, key) => {
      warn(
        `Property "${key}" must be accessed with "$data.${key}" because ` +
        'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
        'prevent conflicts with Vue internals. ' +
        'See: https://vuejs.org/v2/api/#data',
        target
      )
    }
  
    const hasProxy =
      typeof Proxy !== 'undefined' && isNative(Proxy)
  
    if (hasProxy) {
      const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact')
      config.keyCodes = new Proxy(config.keyCodes, {
        set (target, key, value) {
          if (isBuiltInModifier(key)) {
            warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`)
            return false
          } else {
            target[key] = value
            return true
          }
        }
      })
    }
  
    const hasHandler = {
      has (target, key) {
        const has = key in target
        const isAllowed = allowedGlobals(key) ||
          (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data))
        if (!has && !isAllowed) {
          if (key in target.$data) warnReservedPrefix(target, key)
          // 在渲染的时候引用了 key，但是在实例对象上并没有定义 key 这个属性或方法
          else warnNonPresent(target, key)
        }
        return has || !isAllowed
      }
    }
  
    const getHandler = {
      get (target, key) {
        if (typeof key === 'string' && !(key in target)) {
          if (key in target.$data) warnReservedPrefix(target, key)
          else warnNonPresent(target, key)
        }
        return target[key]
      }
    }
  
    initProxy = function initProxy (vm) {
      if (hasProxy) {
        // determine which proxy handler to use
        const options = vm.$options
        const handlers = options.render && options.render._withStripped
          ? getHandler
          : hasHandler
          // 用于修改某些操作的默认行为
        vm._renderProxy = new Proxy(vm, handlers)
      } else {
        vm._renderProxy = vm
      }
    }
  }
  
  export { initProxy }
  