Object.defineProperty
顾名思义,为对象定义属性
定义属性的方法
let person.name = 'wwj';
let person['name'] = 'wwj';
let Object.defineProperty(person, name, {
value: 'wwj'
})
这样看起来Object.defineProperty
定义属性的方法特别麻烦,那为什么还要使用这样的方法定义属性呢?
语法
Object.defineProperty(obj, propertyname, descriptor)
参数
obj
:必需,你要在其上面添加属性,可以是用户自定义的对象,也可以是DOM对象;propertyname
:必需,属性名,是一个字符串类型的值;descriptor
:必需,属性描述符;
属性描述符
value
:属性值,默认为undefined
let person = {};
Object.defineProperty(person, 'name', {
value: 'wwj'
})
console.log(person.name) // wwj
configuable
:如果为false,则任何尝试删除目标属性或修改属性以下特性(writable, configurable, enumerable)的行为将被无效化,直接在对象上定义的属性,这个属性该特性默认值为为true
let person = {};
Object.defineProperty(person, 'name', {
value: 'wwj',
configurable: false
});
delete person.name;
console.log(person.name); // wwj
person.name = 'lingwu';
console.log(person.name); // wwj
// 直接在对象上定义的属性
let person = {};
person.name = 'wwj';
console.log(Object.getOwnPropertyDescriptor(person, 'name'))
// {value: "wwj", writable: true, enumerable: true, configurable: true}
//没有直接在对象上定义的属性,而是用defineProperty定义的属性,writable, configurable, enumerable这些特性都为false
let person = {};
Object.defineProperty(person, 'name', {
value: 'wwj'
})
console.log(Object.getOwnPropertyDescriptor(person, 'name'))
// {value: "wwj", writable: false, enumerable: false, configurable: false}
enumerable
:能否用for-in
遍历出来或者用Object.keys()
列举出来,对于直接在对象上定义的属性,这个特性默认为true
writable
:该属性是否可写,如果设置成false
,那么任何对属性的改写都无效;如果属性是直接被定义在对象上的话,那么这个属性就默认为true
let person = {}
Object.defineProperty(person, 'name', {
value: 'wwj',
writable: false
});
person.name = 'lingwu';
console.log(person.name); // wwj
set
:一旦目标对象访问属性,就会调用这个方法,并返回结果,如果属性不存在该目标对象上,就会返回undefined
;get
:一旦目标对象设置该属性,就会调用这个方法。默认为undefined
实际应用(实现数据的双向绑定)
- 初级版demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" id="txt">
<p id="show_txt"></p>
<script>
let obj = {}
Object.defineProperty(obj, 'txt', {
get: function() {
return obj;
},
set: function(newval) {
document.getElementById('txt').value = newval;
document.getElementById('show_txt').innerHTML = newval;
}
})
document.addEventListener('keyup', function(e) {
obj.txt = e.target.value;
})
</script>
</body>
</html>
vue的双向绑定源码之后再研究补充