一、数据劫持
以原始数据为基础, 对数据进行一份复刻, 复刻出来数据是不允许修改的, 值从原始数据里面获取
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
语法:
配置项Object.defineProperties(给哪一个对象定义, 键名,{配置项})
配置项
- value: 这个属性对应的值
- writable: 该属性是否可以被重写, 默认是 false 不允许被修改
- enumerable: 该属性是否可以被枚举, 默认是 false 不能被枚举到
- get: 是一个函数, 叫做 getter 获取器, 可以决定当前属性的值, 不能与 value writable 同时出现
- set: 是一个函数, 叫做 setter 设置器, 当你需要修改这个属性的时候, 会触发该函
const origin = {
name: 'zs', age: 18
}
const data = {}
Object.defineProperty(data,'name',{
get(){
return origin.name
},
set(val){
origin.name=val
}
})
优点:
能捕获到修改对象属性的行为
缺点:
需要一个额外多余的变量名
数据劫持进阶
Object.defineProperties()
方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
语法:Object.defineProperties(对象, { 配置项 })
为了解决多余变量名的问题, 我们在原始数据中做劫持
把对象中的成员劫持一遍, 放在自己原始对象中
思考:
把自己的成员劫持到自己身上
必然会出现覆盖行为, 所以就需要提前准备备份
过程:
把一个属性先做一个备份
然后把备份劫持成原属性
const data = { name: '张三', age: 18 }
Object.defineProperties(data,{
_name:{
value:data.name,
writable:true
},
name:{
get(){
return data._name
},
set(val){
data._name=val
}
}
})
console.log(data)
二者的区别
Object.defineProperties和defineProperty的区别
defineProperty 是每次操作一个对象成员, 一次只能做一个动作就是把成员定义出来。
defineProperties 是每次操作一个对象成员, 一次可以做多个动作, 可以把当前这个成员, 先做一个备份, 在进行一次劫持。