资讯专栏INFORMATION COLUMN

从ES6的Proxy代理看ES5的代理如何实现

vpants / 1037人阅读

摘要:从的代理看的代理如何实现的代理方法被拦截。。。对代理的实现要说到的代理实现,其中比较有名的就算是的双向绑定中到了和的代理拦截实现了,下面是一个仿照该技术的一个实现拦截器可枚举不能再新的值是的话,进行监听通知订阅者拦截器的出口

从ES6的Proxy代理看ES5的代理如何实现 ES6的Proxy代理

Example

var person = {name:""};
var personCopy = new Proxy(person,{
  get(target,key,receiver){
    console.log("get方法被拦截。。。");
    return Reflect.get(target,key,receiver);
  },
  set(target,key,value,receiver){
    console.log("set方法被拦截。。。")
    return Reflect.set(target,key,value,receiver);
  }
})
person.name = "arvin";  // 未有拦截日志打出
personCopy.name = "arvin";  // set方法被拦截。。。
console.log(person.name);   // 未有拦截日志打出
console.log(personCopy.name);   // get方法被拦截。。。

代码解读:从上述的例子可以看出,被代理对象person的get和set不会经过代理拦截器get,set,而只有代理对象personCopy在get和set方法调用的时候才会经过拦截器,由此可见ES6的代理Proxy并不是一个类似JAVA的AOP,而其实只是将person的引用赋值给了personCopy,让代理对象personCopy和被代理对象person指向了同一个内存空间,下面是我实现的一个用ES5写的Proxy拦截,供大家参考理解Proxy实现原理提供思路:

Example:

/**浅拷贝工具方法**/
function clone(myObj){  
    if(typeof(myObj) != "object" || myObj == null) return myObj;  
    var newObj = new Object();  
    for(var i in myObj){  
      newObj[i] = clone(myObj[i]); 
    }  
    return newObj;  
}
/*代理实现类*/
function ProxyCopy(target,handle){
  var targetCopy = clone(target);
  Object.keys(targetCopy).forEach(function(key){
    Object.defineProperty(targetCopy, key, {
      get: function() {
        return handle.get && handle.get(target,key);
      },
      set: function(newVal) {
        handle.set && handle.set();
        target[key] = newVal;
      }
    });
  })
  return targetCopy;
}

var person = {name:""};
var personCopy = new ProxyCopy(person,{
  get(target,key){
    console.log("get方法被拦截。。。");
    return target[key];
  },
  set(target,key,value){
    console.log("set方法被拦截。。。")
    // return true;
  }
})
person.name = "arvin";  // 未有拦截日志打出
personCopy.name = "arvin";  // set方法被拦截。。。
console.log(person.name);   // 未有拦截日志打出
console.log(personCopy.name);   // get方法被拦截。。。
ES5对Proxy代理的实现

要说到ES5的代理实现,其中比较有名的就算是vue的双向绑定中到了get和set的代理拦截实现了,下面是一个仿照该技术的一个实现:

Example

// 拦截器
function Observer(data) {
    this.data = data;
    this.walk(data);
}
(function($Observer){
    $Observer.prototype = {
        walk: function(data) {
            var me = this;
            Object.keys(data).forEach(function(key) {
                me.convert(key, data[key]);
            });
        },
        convert: function(key, val) {
            this.defineReactive(this.data, key, val);
        },
        defineReactive: function(data, key, val) {
            var childObj = observe(val);
            Object.defineProperty(data, key, {
                enumerable: true, // 可枚举
                configurable: false, // 不能再define
                get: function() {
                    return val;
                },
                set: function(newVal) {
                    if (newVal === val) {
                        return;
                    }
                    val = newVal;
                    console.log("新的值是object的话,进行监听");
                    console.log("通知订阅者");
                    dep.notify();
                }
            });
        }
};
})(Observer);
// 拦截器的出口
function observe(value) {
    if (!value || typeof value !== "object") {
        return;
    }
    return new Observer(value);
};

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84224.html

相关文章

  • Immer.js简析

    摘要:所以整个过程只涉及三个输入状态,中间状态,输出状态关键是是如何生成,如何应用修改,如何生成最终的。至此基本把上的模式解析完毕。结束实现还是相当巧妙的,以后可以在状态管理上使用一下。 开始 在函数式编程中,Immutable这个特性是相当重要的,但是在Javascript中很明显是没办法从语言层面提供支持,但是还有其他库(例如:Immutable.js)可以提供给开发者用上这样的特性,所...

    Aceyclee 评论0 收藏0
  • Immer.js简析

    摘要:所以整个过程只涉及三个输入状态,中间状态,输出状态关键是是如何生成,如何应用修改,如何生成最终的。至此基本把上的模式解析完毕。结束实现还是相当巧妙的,以后可以在状态管理上使用一下。 开始 在函数式编程中,Immutable这个特性是相当重要的,但是在Javascript中很明显是没办法从语言层面提供支持,但是还有其他库(例如:Immutable.js)可以提供给开发者用上这样的特性,所...

    dackel 评论0 收藏0
  • 前端知识点(二)

    摘要:在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行时。 1、元素上下垂直居中的方式有哪些? 元素水平垂直居中的方式有哪些? absolute加margin方案 fixed 加 margin 方案 display:table 方案 行内元素line-height方案 flex 弹性布局方案 transform 未知元素宽高解决方案 absolute加mar...

    zacklee 评论0 收藏0
  • 前端知识点(二)

    摘要:在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行时。 1、元素上下垂直居中的方式有哪些? 元素水平垂直居中的方式有哪些? absolute加margin方案 fixed 加 margin 方案 display:table 方案 行内元素line-height方案 flex 弹性布局方案 transform 未知元素宽高解决方案 absolute加mar...

    lbool 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<