为了账号安全,请及时绑定邮箱和手机立即绑定

ES6新加了Proxy代理(2018-05-16)

标签:
JavaScript

Proxy的实现

//定义一个对象personvar person = {"name":"张三"};//创建一个代理对象pro,代理person的读写操作var pro = new Proxy(person,{    get:function(target,property){        return "李四"
    }
});

pro.name;//李四

set方法

    而上面提到的“编写处理函数“,get方法就是其中一个,除了get方法以外,还有一个很常用的是:set方法,它用于拦截对对象的写操作。

//定义一个对象,含有RMB和dollar属性值var bankAccount = {"RMB":1000,"dollar":0};//创建一个Proxy代理实例var banker = new Proxy(bankAccount,{    //编写get处理程序
    get:function(target, property){        //判断余额是否大于0
        if(target[property] > 0){            //有余额,就返回余额值
            return target[property];
        }else{            //没钱了
            return "余额不足";
        }    
    },    //编写set处理程序
    set:function(target,property,value){        //存入的数额必须是一个数字类型
        if(!Number.isInteger(value)){            return "请设置正确的数值";
        }        //修改属性的值
        target[property] = value;
    }
});

banker.RMB;//结果:1000banker.dollar;//结果:余额不足//修改dollar属性的值,值是字符串类型banker.dollar = "五百";
banker.dollar;//结果:余额不足//修改dollar属性的值,值是数字类型banker.dollar = 500;
banker.dollar;//结果:500

    几乎每一句代码都有注释,这段代码对应的故事情节是这样的:老王有的银行账户里面有一些存款,其中人民币1000元,美元0元。

var bankAccount = {"RMB":1000,"dollar":0};
banker.RMB;//结果:1000banker.dollar;//结果:余额不足

ownKeys( )方法

    ownKeys拦截操作,拦截过滤Object.ownKeys()对对象的属性遍历。

//定义一个对象person,有三个属性let person = {"name":"老王","age":40,"height":1.8};//创建一个代理对象let proxy = new Proxy(person,{    //ownKeys过滤对对象的属性遍历
  ownKeys:function(target){        return ["name","age"]
    }
});Object.keys(person);//结果:["name", "age","height"]Object.keys(proxy);//结果:["name", "age"]

    我们编写的ownKeys方法程序,不管你有多少属性,只返回两个属性name和age。我们看最后两行代码:Object.keys(person); 这里我们不使用代理,直接用keys( )函数遍历person对象,得到的person对象的原本属性"name"、 "age"和"height"。而Object.keys(proxy) 这句代码遍历的是被代理的proxy对象,所以,得到的只是被过滤后的结果:[“name”,”age”]。

has( )方法

    has( )拦截操作:拦截key in object的操作,结果会返回一个布尔值。

var person = {    "name":"张三",    "age":20};var proxy = new Proxy(person, {    has: function(target, prop) {        if(target[prop] === undefined){            return false;
        }else{            return true;
        }
    }
});"name" in proxy;//结果:true"height" in proxy;//结果:false

has( )方法用于是判断是否含有指定的键值对,有,就返回true。否则返回false。

对象含有name属性,所以返回true,没有height属性,返回false。

apply( )方法

    如果被代理的变量是一个函数,那么还会支持一个拦截程序:apply调用。

//创建一个函数fnlet fn = function(){
    alert('我是前端君');
};//创建一个代理实例,代理函数fnlet proxy = new Proxy(fn,{    apply:function(){
        alert('我是隔壁老王');
    }
});

proxy();//结果:我是隔壁老王

    最后一句代码,proxy本身是一个代理实例对象,因为它代理的是一个函数fn,所以可以直接用函数的形式调用proxy( );当它当作函数调用的时候,就会被apply拦截,执行alert('我是隔壁老王')。

Proxy.revocable( )取消代理

    如果创建了代理之后又想取消代理的话,我们可以用Proxy.revocable( )函数来实现,它会返回一个对象,对象中含有一个proxy属性,它就是Proxy的代理实例对象;还有一个revoke属性,它是一个方法,用于取消代理。

//定义一个对象let person = {"name":"张三"};//定义一个代理处理程序let handle = {    get:function(target,prop){        return "李四";
    }
};//使用Proxy.revocable()进行代理let object = Proxy.revocable(person,handle);

object.proxy.name;//结果:李四//调用返回对象object的revoke方法,取消代理object.revoke();

object.proxy.name;//报错,代理被取消

    这个案例大家要注意的是Proxy.revocable( )方法返回的结果,它是一个对象,在控制台打印出来后的结果是:Object{ proxy:Object , revoke:function(){....} }。有一个proxy属性,它就是Proxy代理实例,还有一个属性revoke,它是一个方法,专用于取消代理。

    我们使用object.proxy.name来读取name的属性,由于被代理拦截了,只能读取到“李四”,接着我们调用revoke( )方法取消代理,然后再使用object.proxy.name的时候就会报错了,代理已经不存在了。

1.defineProperty( )

2.deleteProperty( )

3.enumerate( )

4.getOwnPropertyDescriptor( )

5.getPrototypeOf( )

6.isExtensible( )

7.preventExtensions( )

8.setPrototypeOf( )



作者:a小磊_
链接:https://www.jianshu.com/p/d236b3f54d93


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消