Proxy简介和应用

181 阅读2分钟

前言

这是我参与新手入门的第二篇文章。

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对对象进行监听!