(二)Observer将数据对象变成响应式

通过前面的方法我们已经可以实现变化侦测的功能了,但是只做到了对数据对象中的某一个属性进行侦测,而我们希望对这个数据对象中的所有属性进行侦测,因此我们需要封装一个Observer类。

Observer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var arrayKeys = Object.getOwnPropertyNames(arrayMethods)
function Observer (value) {
this.value = value
def(value, '__ob__', this)
if (Array.isArray(value)) {
var augment = hasProto ? protoAugment : copyAugment
augment(value, arrayMethods, arrayKeys)
this.observeArray(value)
} else {
this.walk(value)
}
}

function observe (value) {
if (!value || typeof value !== 'object') {
return
}
var ob
if (
Object.prototype.hasOwnProperty.call(value, '__ob__') &&
value.__ob__ instanceof Observer
) {
ob = value.__ob__
} else if (
(Array.isArray(value) || isPlainObject(value))
&& Object.isExtensible(value)
) {
ob = new Observer(value)
}
return ob
}

首先我们在构造Observer的时候会给我们要观测对象添加一个__ob__属性,这个属性指向这个Observer。通过检查对象上的这个属性我们可以知道这个对象是否已经被观测过,从而避免重复的观测。

阅读全文

(一)Vue中变化侦测的原理

变化侦测

变化侦测是实现响应式的核心。它的作用是当数据变化时,通知视图进行相应的更新。

我们的应用程序在运行时内部的状态会不断发生变化,而变化侦测就是检测到系统哪一个部分发生了变化。

比如在Angular中的脏检测,React中的虚拟DOM,而Vue中实现变化侦测的方式是对数据的劫持(元编程)。

这种方式的好处是在状态发生变化时,我们的程序就立马知道了,然后我们就可以对绑定了这个状态的所有依赖发送通知,让它们进行更新。

在javascript中使用Object.defineProperty可以侦测到一个对象的变化,然而它并不能侦测到数组中的变化,因此我们需要分别讨论。

阅读全文