什么数据劫持?
数据劫持
+ 劫持一个对象内的数据
+ 目的: 通过数据的变化, 让页面或者你的实现发生一些变化
+ 例子: 计数器
=> count 变量作为基础计数器
=> 讲 count 的内容渲染在 p 标签内
=> 今后点击按钮的时候
-> 改变数据(关心数据)
-> 改变页面(关心视图)
+ 例子: 计数器(数据驱动视图)
=> count 变量作为基础计数器
=> 将渲染页面的这个事情和 count 进行关联(只要 count 发生变化, 就自动从新渲染页面)
=> 今后点击按钮的时候
-> 改变数据(关心数据)
----数据驱动视图
数据劫持基本语法
基础数据劫持
语法: Object.defineProperty(target, key, options)
target: 劫持到哪里去
key: 一个键名
options: 该 key 的配置项
value: 表示该 key 对应的 值
enumerable: 表示该属性是否可枚举, 默认是 false
writable: 表示该属性是否可写入, 默认是 false
get 获取器: 是一个函数, 返回值就是该 key 对应的值(注意: 不能和 value 和 writable 一起使用)
set 设置器: 是一个函数, 当你试图修改该 key 的值的是时候, 会触发该函数
意义: 给一个对象设置成员
数据劫持的简单实现
// 尝试
// 准备原始数据
const origin = { name: 'Jack', age: 18 }
// 准备劫持数据对象
// gender 成员是我直接写死的, 没有劫持
const info = { gender: '男' }
// 开始劫持
// 将 origin 内的 name 劫持到 info 内
Object.defineProperty(info, 'name', {
// value: origin.name,
// enumerable: true,
// writable: true,
get () { return origin.name },
set (val) {
// 因为 info对象内的数据是从 origin 劫持过来的
// 当你想要修改数据的时候, 应该修改原始数据
origin.name = val
console.log(`你想把 name 属性的值修改为 ${ val }`)
// 关联渲染页面的逻辑
bindHtml()
}
})
info.name = 'Rose'
// info.gender = '女'
console.log(info)
运行结果:
此方法的缺点:
+ 刚才: Object.defineProperty()
=> 问题1: 会额外增加一个对象作为变量名
=> 问题2: 不好批量操作
+ 现在: Object.defineProperties(target, options)
=> 可以进行批量操作
=> 可以直接在原始对象上进行操作
数据劫持的缺点
+ 后期动态加入的数据, 不会被劫持