# 数据劫持
数据劫持其实就是`Object.defineProperty`这个功能
## 语法
```
Object.defineProperty(obj, prop, desc)
```
1. obj 需要定义属性的当前对象
2. prop 当前需要定义的属性名
3. desc 属性描述符
## 数据属性
通过Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符,存取描述符,下面分别描述下两者的区别:
>[success] value表示它的默认值,
> writable如果为true表示可以被修改,如果为false表示不能被修改(默认值为false)
> configrable 描述属性是否配置,以及可否删除,可以认为是总开关 默认值 true
> enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中 默认值 true
```
let obj= {}
Object.defineProperty(obj, 'name', {
value: '老王',
})
obj.name = '小李'
console.log(obj.name) //老王
```
```
let obj= {}
Object.defineProperty(obj, 'name', {
value: '老王',
writable:true
})
obj.name = '小李'
console.log(obj.name) //小李
```
## 访问器属性
访问器属性提供了getter和setter方法。
>[success] 为了便于理解可以认为下面
> value相当于get
> writable相当于set
```
let obj= {
name:'老王'
}
var value = obj.name;
Object.defineProperty(obj, 'name', {
get(){
return value
},
set(val){
value = val
}
})
obj.name = '小李'
console.log(obj.name) //小李
```
## 常见用法
### 普通对象操作
```
var obj = {
a:1,
b:2
};
Object.keys(obj).forEach(key=>{
jiechi(obj,key,obj[key]);
})
function jiechi(obj,key,value){
Object.defineProperty(obj,key,{
enumerable:true,//可以被for循环便利出来
configurable:true,//可以被删除,可以被修改 如果为 false , 那么不可以修改, 不可以删除.
get(){//获取值
//处理功能
return value+10;
},
set(newVal){//修改值
//处理功能
value = newVal;
}
})
}
```
### 结合DOM操作
```
var obj = {
a:1,
b:2
};
Object.keys(obj).forEach(key=>{
jiechi(obj,key,obj[key]);
})
function jiechi(obj,key,value){
Object.defineProperty(obj,key,{
enumerable:true,//可以被for循环便利出来
configurable:true,//可以被删除,可以被修改 如果为 false , 那么不可以修改, 不可以删除.
get(){//获取值
//处理功能
return value+10;
},
set(newVal){//修改值
//处理功能
document.getElementById('body').innerHTML = newVal;
value = newVal;
}
})
}
```