observe工厂函数
observe函数定义在core/observer/index.js文件中, 我们找到该函数的定义,一点点来看
if (!isObject(value) || value instanceof VNode) { return }
首先判断如果数据不是一个对象或者是一个VNode实例,直接返回。
let ob: Observer | void
接着定义了ob变量,它是一个Observer实例,可以看到observe函数的最后返回了ob.
下面是一个if...else分支:
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { ob = value.__ob__ } else if ( shouldObserve && !isServerRendering() && (Array.isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue ) { ob = new Observer(value) }
首先是if分支,用hasOwn判断了数据对象是否包含__ob__属性,并且判断属性值是否是Observer的实例。如果条件为真的话,就把value.__ob__的值赋给ob。
为什么会有这个判断呢?每个数据对象被观测后都会在该对象上定义一个__ob__属性, 所以这个判断是为了防止重复观测一个对象。
接着是else if分支,这个条件判断有点多,我们一个个来看。
shouldObserve必须为true
该变量也定义在 core/observer/index.js 文件内,
/** * In some cases we may want to disable observation inside a component's * update computation. */ export let shouldObserve: boolean = true export function toggleObserving (value: boolean) { shouldObserve = value }
这段代码定义了shouldObserve变量,初始化为true。接着定义了toggleObserving函数,该函数接收一个参数,这个参数用来更新shouldObserve的值。shouldObserve为true时可以进行观测,为false时将不会进行观测。
!isServerRendering()必须为true
isServerRendering函数用来判断是否是服务端渲染,只有当不是服务端渲染的时候才会进行观测
(Array.isArray(value) || isPlainObject(value)) 必须为真
只有当数据对象是数组或者纯对象时才进行观测
Object.isExtensible(value)必须为true
被观测的数据对象必须是可扩展的, 普通对象默认就是可扩展当。以下三个方法可以将对象变得不可扩展:
Object.preventExtensions()、 Object.freeze()、Object.seal()
!value._isVue必须为真
Vue实例含有_isVue属性,这个判断是为了防止Vue实例被观测
以上条件满足之后,就会执行代码ob = new Observer(value),创建一个Observer实例
Observer 构造函数