zoukankan      html  css  js  c++  java
  • 数据监听

    对象的监听

    es5Object.defineProperty是关键,一个已经定义好的对象,我们可以利用Object.defineProperty方法重写它的属性,添加get,set方法。

    var obj = {
        name:"小明",
        age:18,
        say(){
            return "hello";
        }
    }
    
    for(let key in obj){
        let value = obj[key];  //利用闭包,存值
        Object.defineProperty(obj,key,{
            get(){
                 return value;
            },
            set(val){
                console.log('改变了');
                value = val;
            },
        })
    }
    

    get,set回调里可以塞入我们想要的操作。当然,上述代码如果要严谨点的话,还应当区分是否监听原型链上的属性。可以用hasOwnProperty方法或者Object.keys()方法排除原型链上的属性。

    数组的监听

    因为种种历史原因,数组类型是没法用上面的方法进行监听的,而且因为种种历史原因和实现方式的缘故,数组里的元素改变是没法直接监听到的,(比如 arr[3] = 9),所以只能退而求其次监听数组的方法
    实现思路很简单,在Array和需要监听的数组之间多构造一个数组对象,将监听数组的原型__proto__指向构造的数组对象即可,构造的数组对象自然可以覆写数组方法,并添加自己的操作。

    var overRideArr = [];   //构造的数组对象
    overRideArr['push'] = function(){
        console.log("监听操作");
        return [].push.apply(this,arguments)
    } 
    
    var arr = ['a','b','c']; //  待监听的数组
    arr.__proto__ = overRideArr;  //改变原型指向
    

    为什么要使用__proto__而不是创建一个继承Array的类,并在其内部改写对应方法呢?
    因为除了 new Array(),别的方式无法返回数组类型,即使构造了一个类,new 出来的也是会是个对象。所以通过改变实例的原型指向,是目前监听数组最实用的方式。
    哈?你说别的方式?当然就是直接覆写某个实例数组了,比如这样:

    var arr = ['a','b','c']; //  待监听的数组
    arr['push'] = function(){
        console.log("监听操作");
        return [].push.apply(this,arguments)
    } 
    

    这种方法只有不支持__proto__属性的时候才会用,远没有使用__proto__方便。

    另外如果你真的很喜欢new的方式,其实可以包装一下,弄个形式,但是内里还是上面的代码。

    function  OverArr(arr){
        arr.__proto__ = overRideArr;
        return arr;
    }
    
    var arr2 = ['a','b','c']; //  待监听的数组
    arr2 = new OverArr(arr2);
    //arr2 = OverArr(arr2);    这种写法也一样的
    
  • 相关阅读:
    Java SE(2)
    Java SE(1)
    第二次作业
    Markdown 进阶
    关于主题
    Markdown入门指南
    网络游戏架构与微服务架构简单对比
    微服务框架的存储架构
    轻量级微服务框架的通信架构
    页面静态化
  • 原文地址:https://www.cnblogs.com/grey-zhou/p/8716785.html
Copyright © 2011-2022 走看看