概念
- object.defineProperty用来定义对象的一些属性,或者修改一些已存在的属性
- 语法糖为object.defineProperty(obj,name,desc) 这个方法需要传三个参数,obj是要修改的的对象,name是对其设置的属性名,最后一个是属性描述符
- 一般通过为对象的属性赋值的情况下,对象的属性可以修改也可以删除,但是通过Object.defineProperty()定义属性,通过描述符的设置可以进行更精准的控制对象属性
- 通过Object.defineProperty()为对象定义属性,有两种形式,一种是数据描述符和存取描述符
数据描述符:
只有两个值 value和writable(writable是设置这个属性是不是能被改变),例如:
//用defineProperty进行数据描述符的操作
let obj1 = {}
Object.defineProperty(obj1, 'name',{
value: '11',
writable: true//新建的这个属性是否能被修改,不设置默认是false代表不能被修改
})
console.log(obj1.name) //输出11
obj1.name = 2
console.log(obj1.name)//输出2
存取描述符
是由一对 getter、setter 函数功能来描述的属性:
let obj2 = {}
let c = '这是存取描述符'
Object.defineProperty(obj2,'name',{
get:function(){
return c
},
set:function(val){
c = val
// this.name = val
}
})
console.log(obj2.name) // 输出这是存取描述符
obj2.name='更改属性'
console.log(obj2.name) //输出更改属性
# 数据描述符和存取描述均具有(configurable,enumerable )属性
- configurable该属性值是否能被删除 ,默认是false 不能被删除
- enumerable 该属性是否能被遍历(出现在for,Object.keys()中),默认是false 不能被遍历
- 所以不管是共有的configurable,enumerable也好还是数据描述符中的writable也罢,都是默认false,说白了就是默认不可删除 不可修改 不可遍历
let obj2 = {}
let c = '这是存取描述符'
Object.defineProperty(obj2, 'name', {
get: function() {
return c
},
set: function(val) {
c = val
// this.name = val
},
configurable: true,
enumerable: true
})
console.log(Object.keys(obj2)) //输出['name']
delete obj2.name
console.log(obj2.name) //输出undefind
vue的基本基本数据劫持就是用的这个方式,下面一个简单的数据劫持例子
<input type="text" name="" id='input1' value="">
<span id="span1"></span>
var input1 = document.querySelector('#input1')
var span1 = document.querySelector('#span1')
let data = {}
let value = '开始'
Object.defineProperty(data, 'name', {
get: function() {
return value
},
set: function(val) {
value = val
span1.innerHTML = value
}
})
input1.addEventListener("keyup", function() {
data.name = this.value
// console.log("实现 视图 => 模型");
}, false)