数据劫持
什么是数据劫持
将原始数据 劫持出一份一摸一样, 听起来有点像 浅拷贝
劫持出来的数据, 默认是不可以修改的
语法: Object.defineProperty(那个对象, '对象的key', {配置项})
配置项:
-
value 访问这个值 之后, 得到结果
-
writable 决定当前这个属性能否被修改, 默认是 false
-
enumerable 决定当前这个属性能否被枚举, 决定当前这个属性能否被遍历到
-
getter 是一个函数, 是一个获取器, 当访问这个属性时, 会执行这个函数 + getter 不能和 value writable 一起使用
-
setter 是一个函数, 是一个设置器, 当设置这个属性是, 会执行这个函数
const obj = {}
obj.name = 'QF666'
console.log(obj)
// let str = 'age'
// Object.defineProperty(obj, str, {配置项})
Object.defineProperty(obj, 'age', {
// value: 'QF999',
// writable: true,
enumerable: true,
get() {
// console.log('你当前访问了 这个 age 属性, 触发了 get 函数')
return 'qwer'
},
set(val) {
console.log('你当前想要修改这个 age 属性, 修改的值 是: ', val)
}
})
// console.log(obj)
// for (let k in obj) {
// console.log(k)
// }
console.log(obj.age)
obj.age = 100
实现数据劫持
<body>
<div id="box"></div>
<script>
// 实现数据劫持
const box = document.querySelector('#box')
const obj = {
name: 'QF666',
age: 18
}
console.log('原始对象obj:', obj)
const res = {}
Object.defineProperty(res, 'name', {
get() {
return obj.name
},
set(val) {
// console.log('你想要修改这个属性的值, 新值为: ', val)
obj.name = val
box.innerHTML = `名字: ${res.name}; 年龄: ${res.age}`
}
})
Object.defineProperty(res, 'age', {
get() {
return obj.age
},
set(val) {
// console.log('你想要修改这个属性的值, 新值为: ', val)
obj.age = val
box.innerHTML = `名字: ${res.name}; 年龄: ${res.age}`
}
})
// console.log('数据劫持后的 res: ', res)
// console.log(res.name)
// console.log(res.age)
// res.name = 'QF999'
// res.age = 99
// console.log(res.name)
box.innerHTML = `名字: ${res.name}; 年龄: ${res.age}`
res.age = 99
</script>
</body>
封装数据劫持
<body>
<input type="text" name="" id="inp">
<div id="box"></div>
//封装数据劫持
<script>
const box = document.querySelector('#box')
const obj = {
name: 'QF666',
age: 18
}
function observer(origin, callback) {
const target = {}
for (let k in origin) {
Object.defineProperty(target, k, {
get() {
return origin[k]
},
set(val) {
// console.log('你现在想要修改的key是' , k, '修改的值为', val)
origin[k] = val
callback(target)
}
})
}
callback(target)
return target
}
</script>
//调用数据劫持
<script>
function fn(res) {
box.innerHTML = `名字: ${res.name}; 年龄: ${res.age}`
}
const app = observer(obj, fn)
document.querySelector('#inp').oninput = function (e) {
app.age = e.target.value
}
</script>
</body>