Object.defineProperty()
- Obejct.defineProperty():定义新属性或修改原有的属性
- 语法
- Obejct.defineProperty(obj, prop, descriptor)
- obj:必需,目标对象
- prop:必需,需要定义或者修改的属性的名字
- descriptor:必需,目标属性所拥有的特性
- 第三个参数descriptor说明:以对象形式{}书写
- Obejct.defineProperty(obj, prop, descriptor)
- 第三个descriptor属性的属性值
- value:设置属性的值,默认为undefined
- writable:值是否可以重写,true | false,默认为false
- enumerable:目标属性是否可以被枚举(遍历),true | false,默认为false
- configurable:目标属性是否可以被删除或是否可以再次修改特性,true | false,默认false
- get:值为一个函数,当读取prop属性时,get函数(getter)会被调用,getter的返回值为prop属性的值
- set:值为一个函数,当修改prop属性的值时,set函数(setter)会被调用,且会收到修改的值
- 代码示例:
const person = { name: '张三', sex: '男' } Object.defineProperty(person, 'age', { value: 18 // 设置age的属性值 })
- 语法
双向绑定
- Vue的双向绑定原理:Obejct.defineProperty()的getter与setter
- vue的数据双向绑定原理本质上是利用definePorperty()的getter(get函数)与setter(set函数)实现的
- 代码示例:
let number = 18 const person = { name: '张三', sex: '男' } Object.defineProperty(person, 'age', { // 当读取person对象的age属性时触发getter get () { console.log('已读取age属性值') return number // 将number的值返回给age属性 }, // 当修改person对象的age属性时触发setter,且收到修改的值value set (value) { console.log('已修改age属性值') number = value } })
数据代理
- Vue的数据代理:通过一个对象代理对另外一个对象的属性操作(读/写)
- 本质:利用defineProperty()的getter(get函数)与setter(set函数)
- 代码实例:最简单的数据代理
const obj = { objname: 'obj' } const obj2 = { obj2name: 'obj2' } // 让obj2代理obj Object.defineProperty(obj2, 'x', { get() { return obj2.x }, set(vaule) { obj.objname = value } })
Vue中的数据代理原理(重点)
- vue数据代理原理图
- Vue数据代理:通过vm对象代理data中属性的操作(读/写)
- 好处:更加方便的操作data中的数据;若不使用数据代理,则在html中使用data中的数据则需要以下列形式:{{_data.name}},而不是{{name}}
- 基本原理:
- 通过Object.defineProperty()方法将data中所有的属性添加到vm(vm._data.name, vm._data.address)之上
- 然后为在每一个添加到vm上的属性(name, address)指定setter和getter
- 通过getter读取vm._data.name产生vm.name,读取vm._data.address产生vm.address;通过setter改变vm.name的值映射到_data.name改变_data.name,改变_data.address的值改变_data.address