美文网首页ES6
ES6基本的语法(七) 实现双向绑定(ES6 写法)

ES6基本的语法(七) 实现双向绑定(ES6 写法)

作者: StevenTang | 来源:发表于2021-02-07 15:37 被阅读0次

    Proxy(代理) & (映射)

    Proxy 是在对象之前设置一层“拦截”。外面对该对象的访问,都要先通过这层拦截,可以对外界的访问进行过滤和改写操作。用在这里表示由它来“代理”某些操作,可以译为“代理器”。

    语法和基本使用

    语法

    const p = new Proxy(target, handler)
     // const p = new Proxy(目标对象, 处理程序)
    

    基本使用

    现只说 getset 方法

    
    let data = {
        name: "ccc"
    }
    
    let proxyData = new Proxy(data,{
        get (target, propKey, receiver) {
            console.log(target, propKey, receiver)
            // 打印出 data, 要读取的属性, proxyData
            return Reflect.get(target, propKey); // 等同于 return target[propKey]
        },
        set (target, propKey, value, receiver) {
            console.log(target, propKey, value, receiver)
            // 打印出 data, 要设置的属性, 设置属性的属性值, proxyData
            Reflect.set(target, propKey, value); // 等同于 target[propKey] = value
        }
    })
    
    

    使用 Proxy 对比 Object.defineProperty 不止可以监听对象还可以监听数组的变化

    let data = []
    
    let proxyData = new Proxy(data,{
        get (target, propKey, receiver) {
            return Reflect.get(target, propKey); 
        },
        set (target, propKey, value, receiver) {
            console.log('你进行操作了')
            Reflect.set(target, propKey, value);
        }
    })
    
    data[0] = 10; // 会打印出 你进行操作了
    

    简单的模拟双向绑定

    在上篇我在记 Object.defineProperty 的时候,简单模拟的双向绑定,这次用 Proxy 来模拟一下

    <!DOCTYPE html>
    <html lang="zh">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
        </head>
        <body>
            <input type="text" id='inputDemo'/> 
            <div id="txt"></div>
        </body>
        <script>
            inputDemo.oninput = function(){
                data.box.name.nameData = this.value;
            }
            function upData (){
                txt.innerText = data.box.name.nameData;
            }
            function Observer (obj) {
                if(typeof obj == 'object') {
                    // 循环下层判断是不是对象
                    Object.keys(obj).forEach(function(ele){
                        if(typeof obj[ele] == 'object') {
                            obj[ele] = Observer(obj[ele]);
                        }
                    })
                };
                return new Proxy(obj, {
                    set (target, key, val){
                        if (typeof val === 'object') {
                            val = Observer(val);
                        }
                        Reflect.set(target, key, val);
                        upData();
                    }
                })
            }
            let data = Observer({});
            data.box = {
                value: 'ccc',
                name:{
                    nameData: "ttt",
                }
            }
        </script>
    </html>
    
    

    Proxy 的全部方法

    const p = new Proxy({},{
        // 拦截对象属性的读取
        get(target, propKey, receiver){},
    
        // 拦截对象属性的写入
        set(target, propKey, receiver){},
    
        // 拦截对象 in 操作
        has(target, propKey){},
    
        // 拦截对象 delete 操作
        deleteProperty(target, propKey){}
    
        // 拦截获取代理对象的所有属性键时触发该操作,Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环
        ownKeys(target){}
    
        // 拦截获取对象的某个属性时,进行操作
        getOwnPropertyDescriptorr(target, propKey)
    
        // 拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
        defineProperty(target, propKey, propDesc)
    
        // 拦截让代理对象不可扩展时触发该操作,在执行 Object.preventExtensions(proxy) 时。
        preventExtensions(target){}
    
        // 拦截判断代理对象是否是可扩展时触发该操作,在执行 Object.isExtensible(proxy),返回一个布尔值。
        isExtensible(target){}
    
        // 拦截设置代理对象的原型时触发该操作,在执行 Object.setPrototypeOf(proxy, null) 时,返回一个布尔值。
        setPrototypeOf(target, proto){}
    
        // 拦截函数的代理对象时触发该操作,在执行 proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
        apply(target, object, args){}
    
        // 拦截 Proxy 实例作为构造函数调用的操作,比如在执行 new proxy(...args)。
        construct(target, args){}
    
    })
    

    相关文章

      网友评论

        本文标题:ES6基本的语法(七) 实现双向绑定(ES6 写法)

        本文链接:https://www.haomeiwen.com/subject/mrpztltx.html