在vue2说到双向绑定就不得不说Object.defineProperty()
1、什么是Object.defineProperty
官方说法:方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
个人理解:对某个对象属性的修改或者增加,可以通过内部的
get和set进行对数据的劫持。类似axios的拦截器。
2、用法
Object.defineProperty(obj, prop, descriptor)
obj要定义属性的对象prop要定义或修改的属性的名称descriptor是个对象,里面参数有各种方法
介绍descriptor内属性描述
1、configurable,true: 可以配置对象,删除属性
2、enumerable, true: 可以枚举,枚举就是遍历
3、value 属性的值
4、writable true: descriptor外部可以改变属性value的值
false:外部不可改变
5、get 获取值
6、set 设置值
注意点:get set 不能与value,writable一起使用。互斥。
代码
writable添加属性
let o = {}
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,//遍历
configurable : true
})
console.log(o.a) //输出37
- 利用
get set添加属性
let b = 38
Object.defineProperty(o, "b", {
enumerable : true,
configurable : true,
get() { //o.b就会访问get方法
return b
},
set(v) {
b = v
}
})
console.log(75, o.b)//38
3、再次理解get set
get里面不能拿到当前属性的值,所以要在外面赋值一个变量,通过set来存放这个值
let counter = {
count: 1,
doubleCount: 2
}
let tempCount = 1
Object.defineProperty(counter, 'count', {
get() {
console.log('触发get')
return tempCount
},
set(val) {
tempCount = val
counter.doubleCount = tempCount * 2
return val
}
})
console.log(counter.count)
counter.count = 1
console.log(32, counter) // count 1, doubleCount 2
counter.count = 2
console.log(32, counter) // count 2, doubleCount 4
4、实现个简单的双向绑定
<input type="text" value="222">
<span></span>
/**
* 简单双向绑定
*/
let obj = {}
Object.defineProperty(obj, 'text',{
get(){
console.log('get val')
},
set(v) {
console.log('set val',v)
document.querySelector('span').innerHTML = v
}
})
const inputDom = document.querySelector('input')
inputDom.addEventListener('input',(e)=>{
obj.text = e.target.value
})
PS:详细请看 vue双向绑定原理
5、实现a===1&&a===2&&a===3
- 方法1用
Object.defineProperty
//实现a===1&&a===2&&a===3
window.a = 1
let temp = window.a
Object.defineProperty(window, "a", {
get() {
return temp++
}
})
if (a === 1 && a === 2 && a === 3) {
console.log("true")
}
- 方法2