text: /* @flow */
  
  import { ASSET_TYPES } from 'shared/constants'
  import { defineComputed, proxy } from '../instance/state'
  import { extend, mergeOptions, validateComponentName } from '../util/index'
  
  export function initExtend (Vue: GlobalAPI) {
    /**
     * Each instance constructor, including Vue, has a unique
     * cid. This enables us to create wrapped "child
     * constructors" for prototypal inheritance and cache them.
     */
    Vue.cid = 0
    let cid = 1
  
    /**
     * Class inheritance
     * 类继承
     */
    Vue.extend = function (extendOptions: Object): Function {
      extendOptions = extendOptions || {}
      const Super = this
      const SuperId = Super.cid
      const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
      if (cachedCtors[SuperId]) {
        return cachedCtors[SuperId]
      }
  
      const name = extendOptions.name || Super.options.name
      if (process.env.NODE_ENV !== 'production' && name) {
        validateComponentName(name)
      }
  
      /**
       * 组合继承
       * @param {} options
       */
      // 子类构造函数
      const Sub = function VueComponent (options) {
        this._init(options)
      }
      //将超类的实例赋值给子类的原型
      Sub.prototype = Object.create(Super.prototype)
      // 由于上一步操作后，Sub.prototype.constructor = "Object"
      // 这里改成 Sub.ptototype.constructor = "Sub"
      Sub.prototype.constructor = Sub
      Sub.cid = cid++
      Sub.options = mergeOptions(
        Super.options,
        extendOptions
      )
      Sub['super'] = Super
  
      // For props and computed properties, we define the proxy getters on
      // the Vue instances at extension time, on the extended prototype. This
      // avoids Object.defineProperty calls for each instance created.
      // 对于 props属性和computed计算属性，我们在Vue实例的扩展过程中，在被扩展的原型prototype中定义代理的getters
      // 这样可以避免 Object.defineProperty 调用每一个实例的创建created
      if (Sub.options.props) {
        initProps(Sub)
      }
      if (Sub.options.computed) {
        initComputed(Sub)
      }
  
      // allow further extension/mixin/plugin usage
      Sub.extend = Super.extend
      Sub.mixin = Super.mixin
      Sub.use = Super.use
  
      // create asset registers, so extended classes
      // can have their private assets too.
      ASSET_TYPES.forEach(function (type) {
        Sub[type] = Super[type]
      })
      // enable recursive self-lookup
      if (name) {
        Sub.options.components[name] = Sub
      }
  
      // keep a reference to the super options at extension time.
      // later at instantiation we can check if Super's options have
      // been updated.
      Sub.superOptions = Super.options
      Sub.extendOptions = extendOptions
      Sub.sealedOptions = extend({}, Sub.options)
  
      // cache constructor
      cachedCtors[SuperId] = Sub
      return Sub
    }
  }
  
  function initProps (Comp) { //Sub
    const props = Comp.options.props
    for (const key in props) {
      proxy(Comp.prototype, `_props`, key) //Sub.prototype
    }
  }
  
  function initComputed (Comp) { //Sub
    const computed = Comp.options.computed
    for (const key in computed) {
      defineComputed(Comp.prototype, key, computed[key]) //Sub.prototype
    }
  }
  