前言
这是我参与新手入门的第二篇文章。
js中的Proxy对象是ES2015中新提出的一个新的拦截、监视和操作对象的方式,通过这个对象能够对对象的操作实现拦截,并对拦截的对象进行一些自定义的处理;通俗的说,Proxy就像是公司的门卫,什么人进入公司门卫都要盘查并记录,根据规章制度对于禁止入内的人员予以拒绝,对于允许进出的人使其通过。Proxy也是这样,根据我们创建的自定义处理方法,对一个JS对象进行不同的处理。
Proxy的使用
const p = new Proxy(target, handler)
其中target代表Proxy要拦截的对象,可以拦截的不仅仅是一般的对象,甚至连数组也可以拦截。handler是一个对象,它的属性分别对应Object这个类上的一些方法, 比如:
const handler = {
//这个方法就会在监听的对象调用Object.getPrototypeOf()是,被调用
getPrototypeOf(){
......
}
}
其中,最重要的就是get和set这两种方法,一个是在对象被访问的时候被调用,另一个在对象的某个属性赋值时可以使用
const handler = {
get(target,name,property){
console.log('hello!'); // 在每次读取对象的时候,都会在控制台打印hello!
return Reflect.get(target,name,property); // 将获取的值返回
},
set(target,name,value,property){
console.log('world!'); // 在每次改对象的值时,都会在控制台打印world!
return Reflect.set(target,name,value,property);
}
}
let obj = {a:1}
const pro = new Proxy(obj,handler);
pro.a // 打印出 'hello'和 1
pro.a = 2; // 打印出'world'
利用这个特性,我们可以实现一个简单的双向绑定。
实现一个简单的双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input id="input" type="text" oninput="inputChange()"/>
</br>
<div id="show_value"></div>
<script>
let input = document.getElementById("input");
const showValue = document.getElementById("show_value");
const handler = {
set(target,name,value){
showValue.innerHTML = `值为:${value}`;//spy接到通知之后,更新视图
return Reflect.set(target,name,value);
}
}
let spy = new Proxy(input,handler);
const inputChange = () =>{
spy.value = input.value; // 监听oninput方法,当输入改变时,通知proxy对象spy
}
</script>
</body>
</html>
Vue在Proxy对象出现后,因其较Object.defineproperty更优秀的性能。在Vue选择了Proxy对对象进行监听!