# 數據劫持
數據劫持其實就是`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;
}
})
}
```