让前端飞Vuejs

实现 MVVM (二)- 数据的劫持

2018-10-20  本文已影响9人  passMaker

之前写的 Object.defineProperty 的用法 主要说明了 Object.defineProperty 的一些用法和特性。下面使用 Object.defineProperty 实现一个数据的拦截/监听。

observe() 代码

var data = {
  name: 'evenyao',
  list: [1, 2, 3]
}
observe(data)

function observe(data) {
  if(!data || typeof data !== 'object') return
  for(let key in data) {
    let val = data[key]
    Object.defineProperty(data, key, {
      enumerable: true,
      configurable: true,
      get: function() {
        console.log(`get ${val}`)
        return val
      },
      set: function(newVal) {
        console.log(`changes happen: ${val} => ${newVal}`)
        val = newVal
      }
    })
    // 如果 val 也为对象 递归
    if(typeof val === 'object') {
      observe(val)
    }
  }
}

值得注意的:

  • getset 中的 val 不能直接用 data[key] 替代;
  • for 循环需要使用 let,使用 var 的话则需要使用立即执行函数构建闭包。

测试效果

data.name  
// get evenyao
// "evenyao"

data.name = "Hello"
// changes happen: evenyao => Hello
// "Hello"
data.list[0] = 100
// get 1
// get 2
// get 3
// get 1,2,3
// changes happen: 1 => 100
// 100

data.list
// get 100
// get 2
// get 3
// get 100,2,3
// (3) [(...), (...), (...)]
上一篇下一篇

猜你喜欢

热点阅读