属性描述符
属性描述符(property descriptor)是一个普通的对象,用于描述属性的相关信息,这些相关信息称之为属性元数据(metadata)
我们可以通过Object.getOwnPropertyDescriptor(对象, 属性名)
来得到某个对象的某个属性的描述符,描述符中记录了以下的信息:
- configurable:属性描述符是否可以被重新修改
- enumerable:属性是否是可枚举的,如果为false,则在for-in循环中无法遍历到该属性
- value:属性值
- writable:属性值是否可以被修改
如果要在创建一个属性时定义属性描述符,或者是修改一个属性的描述符,需要使用Object.defineProperty(对象名, 属性名, 描述符)
存取器属性
属性描述符中有两个特殊的配置,分别为get
和set
,它们均是函数。
如果配置了这两个中的任何一个,该属性会变身成为存取器属性。
- 当读取属性值的时候,会运行
get
函数,将get
函数的返回值作为结果 - 当给属性赋值的时候,会运行
set
函数
由于这两个配置的特点,因此具有以下规则:
- get是一个有返回值的无参函数
- set是一个无返回值的单参函数
get
和set
配置,无法与value
和writable
配置共存
属性描述符通常和 Object.defineProperty/Object.defineProperties 一起使用来定义属性,它也会受到诸如 Object.freeze/Object.seal 等方法改变
存取器属性
凡是你给某个属性设置了set,get的话,那么这个属性就变成了存取器属性,也就不是普通的属性了
数据的双向绑定(Vue底层原理)
比如input输入框,内容可以通过你去修改,两者都是互相绑定的!
这也就是存取器属性跟普通的属性的区别!
<!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>
<div>
<p>
<span>姓名:</span>
<span id="spanname">abc</span>
</p>
<p>
<span>年龄:</span>
<span id="spanage"></span>
</p>
</div>
<script>
function User(name, age) {
//this:新的对象
Object.defineProperty(this, "name", {
get: function() {
return document.getElementById("spanname").innerText
},
set: function(val) {
document.getElementById("spanname").innerText = val;
}
})
Object.defineProperty(this, "age", {
get: function() {
return +document.getElementById("spanage").innerText
},
set: function(val) {
if (val < 0) {
val = 0;
} else if (val > 200) {
val = 200;
}
document.getElementById("spanage").innerText = val;
}
})
this.name = name;
this.age = age;
}
var u = new User("daydaylee", 20);
</script>
</body>
</html>