Skip to content

Commit a94c80b

Browse files
committed
Observer refactor: dep.depend()
1 parent bd02b8d commit a94c80b

File tree

5 files changed

+74
-49
lines changed

5 files changed

+74
-49
lines changed

src/instance/scope.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,7 @@ exports._defineMeta = function (key, value) {
221221
enumerable: true,
222222
configurable: true,
223223
get: function metaGetter () {
224-
if (Observer.target) {
225-
Observer.target.addDep(dep)
226-
}
224+
dep.depend()
227225
return value
228226
},
229227
set: function metaSetter (val) {
@@ -233,4 +231,4 @@ exports._defineMeta = function (key, value) {
233231
}
234232
}
235233
})
236-
}
234+
}

src/observer/dep.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ function Dep () {
1111
this.subs = []
1212
}
1313

14+
// the current target watcher being evaluated.
15+
// this is globally unique because there could be only one
16+
// watcher being evaluated at any time.
17+
Dep.target = null
18+
1419
var p = Dep.prototype
1520

1621
/**
@@ -33,6 +38,16 @@ p.removeSub = function (sub) {
3338
this.subs.$remove(sub)
3439
}
3540

41+
/**
42+
* Add self as a dependency to the target watcher.
43+
*/
44+
45+
p.depend = function () {
46+
if (Dep.target) {
47+
Dep.target.addDep(this)
48+
}
49+
}
50+
3651
/**
3752
* Notify all subscribers of a new value.
3853
*/
@@ -45,4 +60,4 @@ p.notify = function () {
4560
}
4661
}
4762

48-
module.exports = Dep
63+
module.exports = Dep

src/observer/index.js

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,6 @@ var uid = 0
1414
var ARRAY = 0
1515
var OBJECT = 1
1616

17-
/**
18-
* Augment an target Object or Array by intercepting
19-
* the prototype chain using __proto__
20-
*
21-
* @param {Object|Array} target
22-
* @param {Object} proto
23-
*/
24-
25-
function protoAugment (target, src) {
26-
target.__proto__ = src
27-
}
28-
29-
/**
30-
* Augment an target Object or Array by defining
31-
* hidden properties.
32-
*
33-
* @param {Object|Array} target
34-
* @param {Object} proto
35-
*/
36-
37-
function copyAugment (target, src, keys) {
38-
var i = keys.length
39-
var key
40-
while (i--) {
41-
key = keys[i]
42-
_.define(target, key, src[key])
43-
}
44-
}
45-
4617
/**
4718
* Observer class that are attached to each observed
4819
* object. Once attached, the observer converts target
@@ -71,9 +42,7 @@ function Observer (value, type) {
7142
}
7243
}
7344

74-
Observer.target = null
75-
76-
var p = Observer.prototype
45+
// Static methods
7746

7847
/**
7948
* Attempt to create an observer instance for a value,
@@ -102,6 +71,20 @@ Observer.create = function (value) {
10271
}
10372
}
10473

74+
/**
75+
* Set the target watcher that is currently being evaluated.
76+
*
77+
* @param {Watcher} watcher
78+
*/
79+
80+
Observer.setTarget = function (watcher) {
81+
Dep.target = watcher
82+
}
83+
84+
// Instance methods
85+
86+
var p = Observer.prototype
87+
10588
/**
10689
* Walk through each property and convert them into
10790
* getter/setters. This method should only be called when
@@ -168,10 +151,8 @@ p.convert = function (key, val) {
168151
enumerable: true,
169152
configurable: true,
170153
get: function () {
171-
// Observer.target is a watcher whose getter is
172-
// currently being evaluated.
173-
if (ob.active && Observer.target) {
174-
Observer.target.addDep(dep)
154+
if (ob.active) {
155+
dep.depend()
175156
}
176157
return val
177158
},
@@ -231,4 +212,35 @@ p.removeVm = function (vm) {
231212
this.vms.$remove(vm)
232213
}
233214

215+
// helpers
216+
217+
/**
218+
* Augment an target Object or Array by intercepting
219+
* the prototype chain using __proto__
220+
*
221+
* @param {Object|Array} target
222+
* @param {Object} proto
223+
*/
224+
225+
function protoAugment (target, src) {
226+
target.__proto__ = src
227+
}
228+
229+
/**
230+
* Augment an target Object or Array by defining
231+
* hidden properties.
232+
*
233+
* @param {Object|Array} target
234+
* @param {Object} proto
235+
*/
236+
237+
function copyAugment (target, src, keys) {
238+
var i = keys.length
239+
var key
240+
while (i--) {
241+
key = keys[i]
242+
_.define(target, key, src[key])
243+
}
244+
}
245+
234246
module.exports = Observer

src/watcher.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,15 @@ p.set = function (value) {
128128
*/
129129

130130
p.beforeGet = function () {
131-
Observer.target = this
131+
Observer.setTarget(this)
132132
}
133133

134134
/**
135135
* Clean up for dependency collection.
136136
*/
137137

138138
p.afterGet = function () {
139-
Observer.target = null
139+
Observer.setTarget(null)
140140
var i = this.deps.length
141141
while (i--) {
142142
var dep = this.deps[i]
@@ -224,4 +224,4 @@ function traverse (obj) {
224224
}
225225
}
226226

227-
module.exports = Watcher
227+
module.exports = Watcher

test/unit/specs/observer/observer_spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ describe('Observer', function () {
6565
}
6666
var dump
6767
// collect dep
68-
Observer.target = watcher
68+
Observer.setTarget(watcher)
6969
dump = obj.a.b
70-
Observer.target = null
70+
Observer.setTarget(null)
7171
expect(watcher.deps.length).toBe(2)
7272
dump = obj.a.b = 3
7373
expect(watcher.update.calls.count()).toBe(1)
@@ -80,9 +80,9 @@ describe('Observer', function () {
8080
// recollect dep
8181
var oldDeps = watcher.deps
8282
watcher.deps = []
83-
Observer.target = watcher
83+
Observer.setTarget(watcher)
8484
dump = obj.a.b
85-
Observer.target = null
85+
Observer.setTarget(null)
8686
expect(watcher.deps.length).toBe(2)
8787
// set on the swapped object
8888
obj.a.b = 5
@@ -209,4 +209,4 @@ describe('Observer', function () {
209209
config.proto = true
210210
})
211211

212-
})
212+
})

0 commit comments

Comments
 (0)