ES6中的Proxy是什么?Proxy的详细分析

本篇文章给大家带来的内容是关于es6中的proxy是什么?proxy的详细分析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

proxy的中文有代理的意思。在其他的程序设计语言中这个单词也具有类似的含义。

它是什么

Proxy是一个构造器。在js中构造器的典型特点就是首字母大写,我们通过new Proxy(原对象,{代理列表})格式去创建对象,创建的这个对象我们称之为代理对象。
即:

代理对象 = new Proxy(原对象,{代理列表})

之所以要额外产生这么一个代理对象,好处在于可以保持原对象不变,在代理对象中添加新的功能,或者是改造某些功能。而这个原对象则可以在适当的时机回滚回去。可以与设计模式中的代理模式对比理解。

使用格式

var obj;var proxyObj = new Proxy(obj, {    对obj的操作1: 函数1,    对obj的操作2: 函数2,    ...    })

登录后复制

入门示例

Proxy的基本示范

var obj = {name:'fan',age:34}console.info(obj.name)var proxyObj = new Proxy(obj,{    get:function(target,key,receiver){console.info(target,key,receiver); return 'no'}})console.info(proxyObj.name) console.info(proxyObj.abc)

登录后复制

解释如下:

proxxy对象是在obj对象的基础之上创建的一个新对象。

proxyObj.name是要去获取proxy对象的name属性。.操作符会自动去调用get()方法。这一点非常重要,在js中,对象是属性的无序集合。对象只有属性,其他什么都没有. 而我们经常说的调用对象的某个方法:例如数组对象arr的sort方法:arr.sort(),这里的sort也是arr对象的属性(更严谨一点,sort是arr.__proto__这个对象的属性),与length属性相比,sort属性的属性值是一个函数,所以在它的后面加()来执行这个函数,而length属性的值是一个数值,所以不需要加()就可以直接使用。再次强调一下:对象的.操作,会自动去调用get。当然,我们平时使用.操作时,是没有感知到这一点的。

在new Proxy的第二个参数中,明确设置了get的方法:当访问proxyObj的任意属性时,输出target,key,receiver的值,并统一返回no。所以proxyObj.name和proxyObj.abc都会得到no。

写到这里你会觉得原对象与代理对象之间有什么关系呢?为什么叫代理呢?

理解代理的作用

代理对象可以理解为明星的经纪人。

外界  原对象;外界  代理对象  原对象;

登录后复制

还以上面的代码为例,改进一下需求:如果有人问obj的名字,就直接告诉对方; 如果有人问obj的年龄,就返回小5岁的年龄。

var obj = {name:'fan',age:34}console.info(obj.age)           // 34var proxyObj = new Proxy(obj,{    get:function(target,key,receiver){        console.info(target === obj);           //true        console.info(receiver === proxyObj);    //true        if('age' === key){            return target[key] - 5;        }        else{            return target[key]        }    }})console.info(proxyObj.age)  // 34- 5 = 29

登录后复制

解释如下:

get函数中的三个参数:target,key,receiver。 target就是原对象j,keys是当前的属性名;receiver是代理对象。你可以在get方法中做任意的自定义的处理。

代理对象与原对象的关系

var arr = [2,1]var proxyArr = new Proxy(arr,{} )proxyArr.push(3);console.info(arr) // [2,1,3]console.info(arr === proxyArr) // falsearr.sort();console.info(proxyArr[0]) // 1

登录后复制

以上代码中,这个代理对象并没有做任何的特殊操作。理解为明星的经理人消极怠工:原封不动地转告外界的信息给明星本身。所以在proxyArr上做到操作会直接影响到arr上。

同理,在arr上的操作,也会影响proxyArr。
但是要注意:proxyArr与arr是两个不同的对象:arr !== proxyArr。

你可能会想一想:为什么proxyArr能够直接使用push这个方法呢?原因是:

proxyArr.__proto__ === arr.__proto__ === Array.prototype

登录后复制

前一个等式成立的原因是由new Proxy的基因决定的:原对象被代理了嘛。

代理列表

在new Proxy的第二个参数中,可以设置的代理属性如下:

var proxyObj = new Proxy(obj, {    get: function(tagert,key,receiver){},    set: function(tagert,key,receiver){},    has: function(tagert,key){},    deleteProperty: function(tagert,key){},    ownKeys: function(tagert){},    getOwnPropertyDescriptor: function(tagert,key){},    defineProperty: function(tagert,key,desc){},    preventExtensions: function(tagert){},    getPrototypeOf: function(tagert){},    isExtensible: function(tagert){},    setPrototypeof: function(tagert,proto){},    apply: function(tagert,obj,args){},    construct: function(tagert,args){},    })

登录后复制

get() 代理的应用

允许数组下标是负值

在js中,数组的有效下表是从0开始的。

var arr = [1,2,3];console.info(arr[0])  // 1console.info(arr[-1]) // undefinedconsole.info(arr[100]) // undefined

登录后复制

值得注意的是,下表越界或者是负值的情况下,得到的结果是undefined,而不是报错。

下面我们希望数组可以取负值下表,规则如下:

-n表示倒数第n个元素。例如:-1表示倒数第一个元素。

使用Proxy解决如下:

var arr = [1,2,3];var proxyArr = new Proxy(arr,{    get: (target,prop)=>{        let index = Number(prop);        if(index < 0){            prop = target.length + index;        }        return target[prop];            }})console.info(arr[-1]);      // undefinedconsole.info(proxyArr[-1]); // 3

登录后复制

注意:

Number()可以把传入的值转成数值型。非数值 –> NaN;

如果是proxyArr.push(3),由于此时的prop是’push’,所以不会进入if分支。

如果是proxyArr[-1],此时的prop是’-1′,所以会进入到if分支:把prop从-1改成 2 ,从而实现了被代理的效果。

此时,完全可以把proxyArr当作一个数组来使用,sort,push等方法均可以调用。Array.isArray(proxyArr) === true

当然,你也可以进一步封装成工厂函数。

function myArr(...args){    var arr = new Array(...args);    var proxyArr = new Proxy(arr,{        get: (target,key)=>{            let index = Number(key);            if(index < 0){                key = target.length + index;            }            return target[key];        }    })    return proxyArr;}var obj = myArr([1,2,3]);console.info(obj[0],obj[-1])

登录后复制

链式运算

var double = n => n*2;var pow2 = n => n*n;var half = n => n/ 2;var add1 = n => n+1;function pipe (num){    let funs = []    let obj = new Proxy({},{        get:function(target,prop){            if(prop === 'end'){                return funs.reduce((val,currentfn)=>currentfn(val),num);            }else{                funs.push(window[prop])            }            return obj;        }    })    return obj;};console.info( pipe(4).double.pow2.end);console.info( pipe(4).pow.double.pow2.add1.end);

登录后复制

以上就是ES6中的Proxy是什么?Proxy的详细分析的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2740054.html

(0)
上一篇 2025年3月8日 02:12:20
下一篇 2025年2月23日 09:10:55

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论