ES6之Proxy及Proxy内置方法

  Proxy是ES6提供的代理器可以起到拦截作用,写法形式如 var proxy = new Proxy(target,handler);参数target表示要拦截的目标对象,handler是用来定制拦截行为。

var proxy = new Proxy({},{ 
    get : function (target,property) { 
        return 'This is Proxy!'; 
    } 
}); 
console.log(proxy.a);    //This is Proxy!
  Proxy支持拦截操作一览:拦截对象的读(get)或写(set)、拦截propKey in proxy的操作(has返回布尔值)、拦截删除(deleteProperty返回一个布尔值)、拦截for(var x in proxy)(enumerate返回一个遍历器)等等。
  set示例代码
let validator = { 
    set : function (obj,prop,value) { 
        if(prop === 'age'){ 
            if(!Number.isInteger(value)){ 
                throw new TypeError('年龄必须是数字!'); 
            } 
            if( value > 100){ 
                throw new TypeError('请输入有效年龄'); 
            } 
        }else{ 
            console.log("输入错误!!请检查");         //输入错误!!请检查
    } 
    obj[prop] = value ; }, 
}; 
let person = new Proxy({},validator); 
console.log(person.sss=100);        //100
console.log(person.age=100);        //100    

  下面写一个在对象内部设置内部属性防止内部属性被外部属性读或写。

var ceshi = {
    get : function (target,key) {
        test(key,'get');
    return target[key];
    },
    set : function (target,key,value) {
    test(key,'set');
    if(key === 'age'){
        if(0<value<100){
                console.log(`年龄是${value}`);
            }
            if(value>100){
            console.log("输入的年龄无效!!!");
            }
            if(value<0){
                console.log("年龄不能为负数");
        }
    }else{
        console.log("你传入的参数不对");
    }
    return true;
    },
}
function test(key,action) {
    if(key[0] === '_'){
        return console.log("你传入的参数不对,请重新传入参数");
    }
}                  
var target = {} ;
var proxy = new Proxy(target,ceshi);

console.log(proxy.age);            //undefined             
console.log(proxy.age = 20);        //年龄是20  20
console.log(proxy.age = 120);        //年龄是120      输入的年龄无效!!! 120
console.log(proxy._age);            //undefined    

  如果想拦截函数的调用那么使用apply()方法,该方法接受三个参数目标对象

var twice = {
    apply(target,ctx,args){
        console.log(args);                //[ 1, 2, 3 ]
        return Reflect.apply(...arguments) * 2;
    }
};
function sum(...arguments) {
    let add = 0;
    for (let i = 0; i < arguments.length; i++){
        add += parseInt(arguments[i]);
    }    
    return add;
    console.log(add);
}                         
var proxy = new Proxy(sum,twice);        
console.log(proxy(1,2,3)+"这个proxy");        //12这个proxy                 console.log(sum(1,2,3)+'这是sum');            //6这是sum

  如果你想取消一个Proxy的示例那么使用revoke()方法,形式是ProxyName.revoke()。  

  还有其他几种方法,我这里面就简单的说下吧,
    1.deleteProperty()该方法用于拦截delete操作,如果这个方法返回false或者是抛出错误当前属性就被delete命令删除
    2.defineProperty()该方法拦截了Object.defineProperty操作
    3.enumerate()该方法用于拦截for...in循环,注意不可与has()方法弄混(has方法用于拦截in操作符)。
    4.has()该方法用于拦截in操作符
    5.construct()方法用于拦截new命令
    6.getOwnPropertyDescriptor()该方法用于拦截Object.getOwnPropertyDescriptor返回一个属性描述对象或者是undefined。
    7.getPrototypeOf()该方法用于拦截Object.getPrototypeOf()运算符以及一些其他操作。
    8.isExtensible()该方法用于拦截Object.isExtensible操作。
9.ownKeys()该方法用于拦截Object.keys()操作。
10.preventExtensions()方法该方法用于拦截Object.preventExtensions()操作。
11.setPrototypeOf()方法该方法用于拦截Object.setPrototypeOf()操作。
原文地址:https://www.cnblogs.com/qiaohong/p/7705189.html