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

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

observe() 代码

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
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 的话则需要使用立即执行函数构建闭包。


测试效果

1
2
3
4
5
6
7
data.name  
// get evenyao
// "evenyao"

data.name = "Hello"
// changes happen: evenyao => Hello
// "Hello"



1
2
3
4
5
6
7
8
9
10
11
12
13
14
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) [(...), (...), (...)]

本文结束  感谢您的阅读
0%