首先要知道对象的一些基本属性
打比方,现在有一个person对象,这个人想去改名,那他的名字就是可以变化的。但是无论怎么操作,他的身份证号都不会改。因此,有必要规定对象的词条中的内容能否被改变。除此以外,还有许多规定的基本属性,对应着这些对象应该怎么被操作。
Object.defineProperty的作用
我们定义对象的时候
这之中,对象的词条的基本属性都是默认的,假如我以后想改名,可以,甚至我想把这个词条删掉,也可以。因此,如果用Object.defineProperty,就可以在操作对象的时候,连带修改属性。
1-writable规定词条中的内容是否可写(默认false)
2-configurable规定词条能否被变更(默认false)
变更=词条变化+配置符变化,配置符就是writable之类
(但是可以新增词条)
如果重新引入一个同名词条。程序会尝试写入,但是因为writable默认值false,所以不能写。程序就尝试先删除再注册,又因为不能删除,所以也是不行的。
(特殊情况:configurable为false时,writable可以从true变成false,不能从false变成true)
2.5-configurable+writable
从以上两个。如果不可写但是可变更。那么只能用Object.defineProperty修改
如果可写但是不可变更。那么只能用=修改
3-enumerable规定词条能否被遍历(默认false)
4-设定常量对象
- 结合writable: false 和 configurable: false 就可以创建一个真正的常量属性(不可修改,不可重新定义或者删除)(但是可以新增词条)
- 为了不让新增,使用Object.preventExtensions()
以上是手动原理,以下是调用方法
- Object.seal()会创建一个密封的对象,这个方法实际上会在一个现有对象上调用object.preventExtensions()并把所有现有属性标记为configurable:false。
- 可以看出,这里如果一开始设定的是writable:true,就会导致可以重赋值,但一般也不会有人设定ture
- 更深度的就是Object.freeze(),调用Object.seal(),并把所有现有属性标记为writable: false
proxy 的优势
vue2.0是使用Object.defineProperty实现的双向绑定,这里,如果我们常规的往对象(或者数组)里赋值一个新的词条和值,页面上会没有相应。我们就用$set来加,这个名令也是使用了Object.defineProperty,因此才能被监测到。
proxy可以在对目标对象设置一层拦截。无论对目标对象进行什么操作,都要经过这层拦截。
1.Object.defineProperty 拦截的是对象的属性,会改变原对象。proxy 是拦截整个对象,通过 new 生成一个新对象,不会改变原对象。
2.proxy 的拦截方式,选择的方式很多,可以监听一些 Object.defineProperty 监听不到的操作,比如监听数组,监听对象属性的新增,删除等。