当前位置: 移动技术网 > IT编程>开发语言>JavaScript > ES6:关于Proxy,你知道多少?

ES6:关于Proxy,你知道多少?

2020年08月10日  | 移动技术网IT编程  | 我要评论
ES6:关于Proxy,你知道多少?概述Proxy用于修改某些操作的默认行为,等同于在语言层面上做出修改,所以属于一种“元编程”,即对编程语言进行编程。Proxy可以理解成在目标对象前架设一层拦截层,外界访问该对象都必须先通过这层拦截,因此提供一种机制可以对外界的访问进行拦截或过滤。实例的方法1.get()get方法用于拦截某个属性的读取操作。let person = { name : '张三'}let proxy = new Proxy(person,{ get

ES6:关于Proxy,你知道多少?

概述

  • Proxy用于修改某些操作的默认行为,等同于在语言层面上做出修改,所以属于一种“元编程”,即对编程语言进行编程。
  • Proxy可以理解成在目标对象前架设一层拦截层,外界访问该对象都必须先通过这层拦截,因此提供一种机制可以对外界的访问进行拦截或过滤。

实例的方法

1.get()

  • get方法用于拦截某个属性的读取操作。
let person = {
    name : '张三'
}

let proxy = new Proxy(person,{
    get : function(target,property){
        if(property in target){
            return target[property];
        }else{
            throw new Error('property ' + property + ' no found!')
        }
    }
})

proxy.name;		//'张三'
proxy.age;		//property age no found!

以上的实例当获取对象没有的属性age时,就会抛出错误;若不通过代理,则会返回undefined;

  • get方法可以继承
let proto = new Proxy({},{
    get(target,propertykey,receiver){
        console.log('get '+ propertykey);
        return target[propertykey];
    }
});

let obj = Object.create(proto);
obj.lalala; 		//get lalala
  • 利用Proxy对象,可以将读取属性的操作变为执行某个函数,从而实现函数的链式操作;
let pipe = (function(){
    return function(value){
        //创建函数执行栈
        let funcStack = [];
        //创建拦截器
        let oproxy = new Proxy({},{
            get: function(pipeObj,fnName){
                //当属性为get,返回函数栈一次执行函数后的结果
                if(fnName === 'get'){
                    return funcStack.reduce(function(val,fn){
                        return fn(val);
                    },value)
                }
                //否则将函数置入函数执行栈中,并返回又一个拦截器
                else{
                    funcStack.push(window[fnName]);
                    return oproxy;
                }
            }
        });
       // 将拦截器返回给pipe 
        return oproxy;
    }
}())

let double = n=>n*2;
let pow = n=>n*n;

pipe(2).double.pow.get;		//16

2.set()

  • set方法用户拦截某个属性的赋值操作
let ageLimit = {
    set : function(obj,prop,val){
        if(prop === 'age'){
            if(!Number.isInteger(val)){
                throw new TypeError('the age must be a integer')
            }
            if(val > 150 || val < 0){
                throw new RangeError('the age must be from 0 to 150')
            }
        }
        
        obj[prop] = val;
    }
}

let person = new Proxy({},ageLimit);
person.age = 200;	//the age must be from 0 to 150;
person.age = 'abc'	//the age must be a integer;
person.age = 20;	//正常
person.age;			// 20;
  • 通过ageLimit拦截器,可以及时对用户的数据输入做数据验证,以保证数值规范;
  • 有时候,我们会在对象上设置内部属性,属性名的第一个字符为下划线’_’,表示该属性不能被外部访问或使用。结合get和set方法,就可以做到防止内部属性被外部读写;
let handler = {
    get (target , key){
        invariant(key,'get');
        return target[key];
    },
    set (target , key , value){
        invatiant(key,'set');
        taget[key] = value;
        return true;
    }
}


function invariant(key,action){
    if(key[0] === '_'){
        throw new Error('no allowed to ' + action + ' the property');
    }
}

let target = {
    _name : '张三',
    _age : 20
};
let proxy = new Proxy(target,handler);
proxy._name;	// no allowed to get the property
proxy._age = 12	// no allowed to set the property

3.apply()

  • apply方法拦截函数的调用、call、apply操作
  • apply方法接收三个参数:目标对象、目标对象的上下文的this、目标对象的参数数组
let target = function(){
    console.log('I am the target');
}

let handler = {
    apply : function(){
        console.log('I am the apply');
    }
}

let p = new Proxy(target,handler);

p();	//I am the apply;

4.其他方法

  1. has(target,propkey)

    • 拦截hasProperty()propkey in proxy操作,返回一个布尔值;
  2. deleteProperty(target,propkey)

    • 拦截delete proxy[propkey]操作,返回一个布尔值;
  3. ownKeys(target)

    • 拦截Object.getOwnPropertyNarnes(proxy)Object.getOwnPropertySyrnbols (proxy)Object.keys(proxy),返回一个数组。该方法返回目标对象所有自身属性的属 性名,而 Object .keys()的返回结果仅包括目标对象自身的可遍历属性;
  4. getOwnPropertyDescriptor(target,propkey)

    • 拦截 Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象;
  5. defineProperty(target,propkey)

    • 拦截 Object.defineProperty(proxy, propKey, propDesc)Object.define Properties(proxy, propDescs),返回一个布尔值;
  6. preventExtensions(target)

    • 拦截 Object . preventExtensions (proxy) ,返回一个布尔值;
  7. getPrototypeOf(target)

    • 拦截Object.getPrototypeOf(proxy),返回一个对象;
  8. isExtensible(target)

    • 拦截Object.isExtensible(proxy),返回一个布尔值;
  9. setPrototypeOf(target)

    • 拦截Object.setPrototypeOf(proxy,proto),返回一个布尔值;若对象为函数,则还有二外两种操作可以拦截(apply,construct)
  10. construct(target,args)

    • 拦截Proxy实例作为构造函数调用的操作,比如 new proxy(…args);

本文地址:https://blog.csdn.net/yivisir/article/details/107895266

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网