[Javascript] Using defineProperty to observe the object props changes

const obj = {
  a: 1,
  b: 2,
  c: {
    a: 1,
    b: 2,
  },
};

function isObject(val) {
  return val !== null && typeof val === "object";
}

function observe(obj) {
  for (let key in obj) {
    let v = obj[key];
    if (isObject(v)) {
      observe(v);
    }
    Object.defineProperty(obj, key, {
      get() {
        console.log(key, "read", v);
        return v;
      },
      set(val) {
        if (val !== v) {
          console.log(key, "set", val);
          v = val;
        }
      },
    });
  }
}

observe(obj);

obj.a;
obj.a = 3;
obj.c.a;
obj.c.b = 3;

console.log(JSON.stringify(obj));

/*
a read 1
a set 3
c read { d: [Getter/Setter], e: [Getter/Setter] }
d read 1
c read { d: [Getter/Setter], e: [Getter/Setter] }
e set 3
a read 3
b read 2
c read { d: [Getter/Setter], e: [Getter/Setter] }
d read 1
e read 3
{"a":3,"b":2,"c":{"d":1,"e":3}}
*/

 

Using defineProperty can only observe the existing props, if we add a new prop, then we are not able to observe it anymore

observe(obj);

obj.f = 123; // not albe to observe the changes, due to observe function has been called with existing properties

 

Also we are not able to observe deleted prop:

observe(obj);

delete obj.b;

 

So defineProperty is limited only to existing props of the object. 

If we want to achieve better result, we have to use Proxy

posted @ 2024-10-09 14:58  Zhentiw  阅读(1)  评论(0编辑  收藏  举报