原理

数据劫持最基本的原理就是通过遍历为对象的每个属性都添加 getter,setter。

实现

更新器

当数据发生变化时会调用 updater。

  1. function updater(){
  2. console.log('更新视图')
  3. }

遍历属性并添加监听

  1. const data = {
  2. name: 'rj',
  3. age: 18,
  4. address: {
  5. location: '回龙观'
  6. }
  7. }
  8. function observer(obj) {
  9. if (typeof obj !== 'object') return obj;
  10. for (let key in obj) {
  11. if (obj.hasOwnProperty(key)) {
  12. defineReactive(obj, key, obj[key])
  13. }
  14. }
  15. }
  16. function defineReactive(obj, key, value) { //value是个闭包
  17. //递归
  18. observer(value);
  19. Object.defineProperty(obj, [key], {
  20. get() {
  21. return value;
  22. },
  23. set(newValue) {
  24. if(value !== newValue){
  25. updater(value, newValue);
  26. //如果新值也是对象,也需要添加监听
  27. observer(newValue);
  28. value = newValue;
  29. }
  30. }
  31. })
  32. }
  33. observer(data);
  34. console.log(data.name, data.age); //rj 18
  35. data.name = 'cj';
  36. data.address.location = '山里';
  37. data.address = {location:'天上'}
  38. //如果不给新赋值添加监听,此处则不会触发更新,即29行
  39. data.address.location = '人间';
  40. /*
  41. rj cj
  42. 开始更新
  43. 回龙观 山里
  44. 开始更新
  45. { location: [Getter/Setter] } { location: '天上' }
  46. 开始更新
  47. 天上 人间
  48. 开始更新
  49. */