简介
属性描述符是JS对象的内容
属性描述符包括数据描述符和存取描述符。
存取描述符作用
对象属性的赋值,可以通过set和get方法来处理,可以在方法中就为传入的值做出限定,如age不可能为负数等
这一点,Vue框架中的计算属性就是基于此实现的,dom操作中改变innerHtml等属性值动态改变UI也是基于此实现的
存取描述符例子
defineProperty是Object的静态方法,使用:
Object.defineProperty(obj, prop, descriptor)
参数
obj
要定义属性的对象。
prop
要定义或修改的属性的名称或 Symbol
descriptor
要定义或修改的属性描述符
注意事项:
在get和set方法中不要提及使用到属性描述符定义的对象属性,否则会陷入无限递归,满栈报错。可以通过一个中间变量传递值
function Demo(x) {
var _x = x//中间变量,_x初始化为x中的值
Object.defineProperty(this, 'x', {
get: function () {//get方法取_x得内容相当于取到x的内容
console.log("get")
return _x
},
set: function (x) {//set方法将_x内容更新。再次使用get方法,照常取_x这个中间变量
if(x>100){
x = 100
}
if(x<0){
x = 0
}
_x = x
console.log("set")
}
})
this.x = _x
}
var obj = new Demo(50)
descriptor
描述符可拥有的键值
| configurable | enumerable | value | writable | get | set | |
|---|---|---|---|---|---|---|
| 数据描述符 | 可以 | 可以 | 可以 | 可以 | 不可以 | 不可以 |
| 存取描述符 | 可以 | 可以 | 不可以 | 不可以 | 可以 | 可以 |
数据描述符特点是value和writable可用,没有使用get且set方法,一旦使用则变为存取描述符,value和writable就失效了
enumerable
- 控制属性是否可遍历,定义为false后,无法被forin,forof遍历到
- 原型链上的一些属性之所以在控制台中看到,而没有遍历出来,就是操作了该属性为false
- 通过Object.getOwnPropertyDescriptor方法获取到的描述符不能直接通过对象.enumerable=bool值的方式来生效配置(虽然值确实改掉了)
例子
var student = {
dag:"awe",
name:"zhangsan",
age:19,
}
var x = Object.getOwnPropertyDescriptor(student,"name")
// x.enumerable = false 无效,依旧可遍历
Object.defineProperty(student,"name",{//有效操作,使得name不可遍历
enumerable:false
})