搁置了几天我仍是决定再次重写!html
下边咱们来具体聊聊先从defineProperty开始提及vue
//defineproperty 有个定义object属性的功能,应该没几我的用,由于相对于obj.a = 1这种方式简直不能再难用。 //一般咱们定义obj属性 let obj = { a:1 } obj.b = 2 obj['c'] = 3 console.log(obj)//{a: 1, b: 2,c: 3} Object.defineProperty(obj,'d',{ value: 4 }) console.log(obj)//{a: 1, b: 2,c: 3,d:4} //defineProperty能够定义对象属性 //也能够修改 Object.defineProperty(obj,'b',{ value: 5 }) console.log(obj)//{a: 1, b: 5, c: 3, d: 4}
//对你没看错defineProperty有这个功能,不知能够定义新的属性还能够修改,这么逆天难用的功能为何还要造出来?说这个有什么用?别急往下看segmentfault
descriptor (必须有 官方说的我理解不了,我理解的是 属性描述
一、简单点就是 设置属性的值value,
二、是否可操做属性值 writable,
三、是否可修改配置configurable若是值为false descriptor内的属性都不可操做)
四、是否可枚举enumerablespa
先作了介绍咱们下边来证实下双向绑定
//栗子仍是这个栗子 let obj = { a: 1 } Object.defineProperty(obj, 'b', { value: 2, writable: false//不可修改 }) obj.b = 3 console.log(obj) //{a: 1, b: 2} 还真是不能够 //难道是姿式不对? Object.defineProperty(obj, 'b', { value: 3 }) console.log(obj)//{a: 1, b: 2} 同样的效果 和姿式无关。
//configurable 这个比较厉害 控制descriptor内属性都不可改变不知道是否是真的code
//仍是这个栗子htm
let obj = { a: 1 } Object.defineProperty(obj, 'b', { value: 2, //writable: false//不可修改 configurable: false }) obj.b = 5 console.log(obj)//[1,2]
对否可枚举对象
let obj = { a: 1 } Object.defineProperty(obj, 'b', { value: 2, //writable: false//不可修改 //configurable: false enumerable: false }) //obj.b = 5 console.log(Object.keys(obj))//["a"]
接了下来讲到重点: set和get这也是vue3.0前observe的实现原理ip
let obj = { a: 1 } let newValue = 45 Object.defineProperty(obj, 'b', { get(value) { console.log('获取') return value }, set(newValue) { console.log('设置') value = newValue } }) obj.b = 6 //设置 obj.b //获取
知道用法了咱们来实践一下rem
//html <div></div> <input type="text"> //js //相似 vue的data let obj = {} /* *obj 要劫持的对象 *name 要劫持对象的属性 *callback 劫持之后的操做 */ function watch(obj, name, callback) { let value = obj.name Object.defineProperty(obj, name, { set(msg) { // 触发setter给obj赋值 value = msg //执行劫持后的操做 callback(value) }, get() { //返回获取属性值 return value } }) } // function doSomething(value) { document.querySelector('div').innerHTML = value document.querySelector('input').value = value } //监听input变化 //能够参考全兼容版:https://segmentfault.com/a/1190000017524278 document.querySelector('input').addEventListener('input', (e) => { obj['msg'] = e.target.value }) watch(obj, 'msg', doSomething)
效果:
一、input输入改变div内容
二、改变obj name属性
三、获取改变后的obj属性name
简单的用defineProperty实现了双向绑定
欢迎吐槽!您的点赞是我继续的动力!谢谢