# Observe

  • 处理响应式
  • 通过Object.defineProperty递归处理vm._data对象的属性。数组则通过修改原型链的方法来实现发布订阅
  • 通过defineReactive来为每个属性创建dep,触发gettter的时候依赖收集,触发setter时,通过dep.notify(),调用dep.subs中所有watcher.update()去做更新操作。
export function observe (value: any, asRootData?: boolean) {
  // 非对象和 Vnode 不做处理
  if (!isObject(value) || value instanceof VNode) return
  let ob: Obsever | void
  // 如果已经创建了 wathcer 则直接返回
  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
    ob = value.__ob__
  } else if {
    ob = new Observer(value)
  }
  if (asRootData && ob) {
    ob.vmCount++
  }
  return ob
}

# Observer

export class Observer {
  value: any,
  dep: Dep,
  vmCount: number
  
  constructor (value: any) {
    this.value = value
    this.dep = new Dep()
    def(value, '__ob__', this)
    if (Array.isArray(value)) {
      // 修改数组原型链的方法
      // ...
    } else {
      // 如果是对象则为每个属性设置响应式
      this.walk(value)
    }
  }
  
  // 为每个key绑定响应式
  walk (obj: Object) {
    const keys = Object.keys(obj)
    for (let i = 0; i < keys.length; i++) {
      defineReactive(obj, keys[i])
    }
  }
}

# defineReactive

export function defineReactive (
  obj: Object,
  key: string,
  val: any,
  customSetter?: Function,
  shallow?: boolean
) {
  const dep = new Dep()
  // 获取 obj[key] 的属性描述符,如果是不可配置对象 直接 return
  const property = Object.getOwnPropertyDesciptor(obj.key)
  if (property && property.configurable === false) return
  
  // 处理 computed 的 get 与 set
  const getter = property && property.get
  const setter = property && property.set
  // 普通对象的情况下值为 obj[key]
  if ((!getter || setter) && arguments.length === 2) {
    val = obj[key]
  }
  
  // 递归
  let childOb = !shallow && observe(val)
  
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    // 拦截读取操作
    get: function reactiveGetter () {
      // data 中的值只会有 dep 不会有 wathcer,因为 data 中的值不依赖任何值,所以不需要创建 watcher
      const value = getter ? getter.call(obj) : val
      /** 
       * Dep.target 保存了当前正在触发 get() 的 Watcher
       * 如果存在 Dep.target 说明有 watcher 被创建且引用了当前值(依赖当前值)
       * 不存在 Dep.target 就代表正常的使用 则不需要依赖收集
      */
      if (Dep.target) {
        // 依赖收集。 Dep.target.addDep(this)
        // addDep 会调用添加的 dep.addSub 在将 wathcer 添加到 dep.subs 中。
        dep.depend()
        if (childOb) {
          childOb.dep.depend()
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      const oldVal = getter ? getter.call(obj) : val
      // 如果 newVal 与 oldVal 值一样则不触发更新
      if (newVal === oldVal || (newVal !== newVal && oldVal !== oldVal)) return
      // 不存在 setter 说明是只读属性 直接 return
      if (getter && !setter) return
      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }
      // 新值也是响应式
      childob = !shallow && observe(newVal)
      // 更新依赖
      dep.notify()
    }
  })
}