image.png
其实这里挺好理解的,首先什么情况下childOb会不为空呢?当val对象或者是数组的时候,也就是说,当**val**是对象或者数组的情况下,触发get函数(也就是说读取该值)的时候,依赖会被添加到两个dep实例里面:

  1. 一个是**defineReactive**函数构建的闭包中的**dep**
  2. 另一个是这个对象或者数组对应的observer实例的**dep**属性。

    为什么Vue要将依赖进行两处的添加呢?

    有时候会觉得很奇怪为什么要将依赖添加到两个不同的地方。其实他们都有自己的用途。我举个例子:
    1. let data = {
    2. obj: {}
    3. }

    当我们进行对**data.obj**进行赋值操作的时候,针对这个属性的依赖或者说观察者是不是应该进行**update**呢?这是当然的。所以这个时候,**Vue****set**函数中就使用**defineReactive**中的**dep**进行**notify**操作。 当我们对这个**obj**对象进行属性删除(**$delete**)、属性添加(**$set**)的时候,针对 这个属性的观察者是不是应该更新,这是理所当然的。但是由于上述行为无法触发**set**函数,所以导致观察者无法触发**update**。这个时候挂载在**observer**实例身上的**dep**实例就发挥作用了。我们可以**obj.__ob__.dep.notify()**这样来触发针对**obj**属性的那些观察者更新。 同样的,数组是一样的道理,**push**等操作都是无法触发**set**函数的,所以也是通过第二个**dep**实例来触发观察者们的更新。