# 实用-手写响应式

# Object.property

var obj = { name: "Aaron" };

function reactive(target) {
  if (typeof target === "object" && target !== null) {
    for (let key in target) {
      defineReactive(target, key, target[key]);
    }
  }
}

function defineReactive(target, key, val) {
  Object.defineProperty(target, key, {
    enumerable: true,
    configurable: true,
    get: function () {
      console.log('get invoked');
      return val;
    },
    set: function (newVal) {
      if (newVal != val) {
        console.log(`set invoked ${val} => ${newVal}`);
        val = newVal; // 这里利用到了闭包,可以直接赋值代替 target[key],后者会导致堆栈溢出
      }
    },
  });
}

reactive(obj);
console.log(obj.name);
obj.name = "Vera";
console.log(obj.name);
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

# Proxy

var obj = { name: "Aaron" };

function reactive(target) {
  return new Proxy(target, {
    get: function(obj, key) {
      console.log('get invoked')
      return obj[key];
    },
    set: function(obj, key, newVal) {
      let val = obj[key];
      if (val !== newVal) {
        console.log(`set invoked change from ${val} => ${newVal}`)
        obj[key] = newVal;
      }
    }
  })
}

let proxyObj = reactive(obj);
console.log(proxyObj.name);
proxyObj.name = "Vera";
console.log(proxyObj.name);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
上次更新: 1/13/2022, 8:26:50 AM