作为一个后端开发,对于set
和get
一般都不会陌生。在面向对象开发中,一个对象一般都有 get 和 set 的属性,赋值既是set
,得值就是get
。刚接触 JavaScript 的时候,似乎还没有这个特性(也可能自己太菜),随着 Vue.js 的流行慢慢火热起来。其实原理很简单,就是看怎么搞。
对象描述类型
通俗的来说就是一个对象假设 var obj = { a: 1 }
,有一种东东叫做属性描述对象,用于解释 obj.a
的一些属性。
有且只有两种类型:
- 数据型描述符
- 控制型描述符
所有对象的 key 的描述对象类型必须是两者之一。
数据型描述符(data descriptors)
也是默认的方式,拥有以下四个元属性:
value
value
是该属性的属性值,默认为undefined
。writable
writable
是一个布尔值,表示属性值(value)是否可改变(即是否可写),默认为true
。enumerable
enumerable
是一个布尔值,表示该属性是否可遍历,默认为true
。如果设为false
,会使得某些操作(比如for...in
循环、Object.keys()
)跳过该属性。configurable
configurable
是一个布尔值,表示可配置性,默认为true
。如果设为false
,将阻止某些操作改写该属性,比如无法删除该属性,也不得改变该属性的属性描述对象(value
属性除外)。也就是说,configurable
属性控制了属性描述对象的可写性。
控制性描述符(accessor descriptors)
也有用enumberable
和configurable
,定义内容也基本一致。区别是另外两个是 get
和 set
相当于面向对象的setter
和getter
。
get
get
是一个函数,表示该属性的取值函数(getter),默认为undefined
。set
set
是一个函数,表示该属性的存值函数(setter),默认为undefined
。
Object.getOwnPropertyDescriptor()
获得属性描述对象。
1 | var obj = { p: 'a' }; |
Object.getOwnPropertyNames()
1 | Object.keys([]) // [] |
和 Object.keys()
的区别:
- 无论
enumerable
是否,Object.getOwnPropertyNames()
全部返回,而Object.keys()
只会返回为true
的属性。
Object.defineProperty()(Object.defineProperties())
定义属性描述的方法。
1 | Object.defineProperty(object, propertyName, attributesObject) |
1 | var obj = {}; |
Object.defineProperties()
用于一次修改多个属性
1 | var obj = Object.defineProperties({}, { |
Object.prototype.propertyIsEnumerable()
实例对象的propertyIsEnumerable
方法返回一个布尔值,用来判断某个属性是否可遍历。
1 | var obj = {}; |
然后就是 Vue.js 的实现了
表示没看过源码,所以这是一个小 demo。但是实际实现方式应该就是这样。
1 | class Vue { |