风华正茂、时光流逝、真爱时光、努力创建辉煌。

【ES6】---JavaScript(三)

 

一、proxy介绍

Proxy(代理) 是 ES6 中新增的一个特性。


作用:在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。很类似于设计模式中的代理模式

二、基本用法

let p = new Proxy(target,handler)

  

参数:

    target 是用Proxy包装的被代理对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

    handler 是一个对象,其声明了代理target 的一些操作,其属性是当执行一个操作时定义代理的行为的函数。

特点:

  • 可以劫持整个对象,并返回一个新对象

  • 有13种劫持操作

     

  • handler代理的一些常用的方法有如下几个:

    • get:读取

    • set:修改

    • has:判断对象是否有该属性

    • construct:构造函数

    • apply:当目标对象是一个函数的时候

    • deleteProperty: 用于拦截delete操作

三、get/set方法

    var target = {
        name:"Alley",
        age:19,
        sex:"男"
    }

    var p = new Proxy(target,{
        get(obj,attr){
            console.log("属性被访问了");
        },
        set(obj,attr,value){
            console.log("属性被设置了");
        }
    })
    p.name;
    p.name = "巷子";

  

get函数:当访问target对象身上的一些属性的时候就会触发get函数,get函数接收2个参数

           参数1:代理的对象也就是target  

           参数2:访问的属性

 

set函数: 当设置target对象身上的一些属性的时候就会触发set函数,set函数接收3个参数  

           参数1:代理的对象

           参数2:设置对象的属性

           参数3:设置对象属性的值

 

 

四、get/set使用场景

 

1、虚拟属性

var target = {
    firstName:"张",
    lastName:"小凡"
}

var p = new Proxy(target,{
    get(obj,attr){
        if(attr == "fullName"){
            return [obj.firstName,obj.lastName].join("");
        }
        return obj[attr]
    },
    set(obj,attr,value){
        if(attr == "fullName"){
            var fullNameInfo = value.split(" ");
            obj.firstName = fullNameInfo[0];
            obj.lastName = fullNameInfo[1];
        }else{
            obj[attr] = value;
        }
    }
})

console.log(p.fullName);//张小凡
p.fullName = "小 甜甜";
console.log(p.firstName);//小
console.log(p.lastName);//甜甜

  

2、私有属性

//把_开头的变量都认为私有变量

var target = {
    name:"张三",
    age:19,
    _sex:"女"
}


var p = new Proxy(target,{
    get(obj,attr){
        if(attr.startsWith("_")){
            console.log("私有属性不允许被访问");
            return false;
        }

        return obj[attr];
    },
    set(obj,attr,value){
        if(attr.startsWith("_")){
            console.log("私有属性不允许被设置");
            return false;
        }
        obj[attr] = value;
    },
    has(obj,attr){
        if(attr.startsWith("_")){
            return false;
        }
        return (attr in obj);
    }
})

  

五、函数拦截

 

apply:当目标对象是一个函数,且它被调用时,就是被apply方法拦截。

参数:apply(target,context,arguments)

           target:目标对象

           context:目标对象的上下文对象(this)

           arguments:目标对象的参数数组



construct:construct方法用于拦截new命令,意思就是你在new目标对象的时候,会走constrcut(){}这里。

参数:construct(target,arguments)

           target:目标对象

           arguments:构造函数的参数对象

 

  function fn(a,b){}

    var handler = {
        apply: function (target, context, args) {
            console.log(target, context, args)
            return args[0];
        },

        construct: function (target, args) {
            return { value: args[1] };
        }
    };


    var p = new Proxy(fn,handler);


    console.log(p(1,2)) //1
    console.log(new p(1,2)) // {value:2}

  

 https://www.cnblogs.com/yuanjili666/p/11683393.html

posted @ 2019-10-16 09:06  野马,程序源改造新Bug  阅读(89)  评论(0编辑  收藏  举报