# watcher&&dep

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    class Watcher {
      newDepIds = []
      newDeps = []
      depIds = []
      constructor(fn, cb) {
        Dep.target = this
        fn()
        this.cb = cb
      }
      addDep (dep) {
        const id = dep.id
        if (!this.newDepIds.includes(id)) {
          this.newDepIds.push(id)
          this.newDeps.push(dep)
          if (!this.depIds.includes(id)) {
            dep.addSub(this)
          }
        }
      }
      update () {
        this.cb()
      }
    }

    class Dep {
      static target = null;
      id = 0;
      subs = [];

      constructor() {
        this.id = 1;
        this.subs = [];
      }

      addSub(sub) {
        this.subs.push(sub);
      }

      removeSub(sub) {
        remove(this.subs, sub);
      }

      depend() {
        if (Dep.target) {
          Dep.target.addDep(this);
        }
      }

      notify() {
        const subs = this.subs.slice();
        for (let i = 0, l = subs.length; i < l; i++) {
          subs[i].update();
        }
      }
    }

    function defineReactive(obj, key, val) {
      const dep = new Dep();
      Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
          if (Dep.target) {
            dep.depend();
          }
          return val;
        },
        set: function reactiveSetter(newVal) {
          val = newVal;
          dep.notify();
        },
      });
    }

    
    
    const o = {
      a: 1
    }
    defineReactive(o, 'a', 1)

    new Watcher(() => {
      return o.a
    }, function() {
      console.log(11111111)
    })

    o.a = 2
  </script>
</html>

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

new Watcher -> Dep.targer赋值 data.getter -> dep.depend -> dep添加watcher实例

data.setter -> dep.notify() -> watcher update

最后更新时间: 5/26/2021, 5:52:52 PM