Proxy

1、概述

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,就是对语言层面上的逻辑进行的修改

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

2、基本使用

let obj = {
    a:100,
    b:200,
    c:300
}
let proxyObj = new Proxy(obj,{
    get:function(){
        return "获取值的内容"
    },
    set:function () {
        console.log("设置的内容")
    }
})
console.log(proxyObj.c)
proxyObj.c = 666
console.log(proxyObj)

上面的proxyObj是设置可以拦截的对象,第一个拦截obj参数是对应要拦截的对象内容,第二个参数是拦截行为,所有的行为在一个对象中

行为的内部可以设置参数

let obj = {
    a:100,
    b:200,
    c:300
}
let proxyObj = new Proxy(obj,{
    get:function(target,key){
        return `拦截目标${target} ,拦截属性${key} ,拦截目标属性的值${target[key]}`
    },
    set:function (target,key,value) {
        console.log(`设置目标${target} ,设置属性${key} ,设置目标属性的值${value}`)
    }
})
console.log(proxyObj.b)
proxyObj.c = 666
console.log(proxyObj)

get方法主要的参数有两个,第一个target指的目标对象,key表示获取的该对象的key

set方法主要的参数有三个,第一个target指的目标对象,key表示获取的该对象的key,value表示要设置的value

3、Proxy可以当做原型对象

let proxy = new Proxy({},{
    get:function () {
        return 35
    },
    set:function () {

    }
})
let obj = Object.create(proxy)
console.log(obj.time) 35

4、get方法

get方法用于拦截某个属性的读取操作

let person = {
    name:"小明",
    age:"19岁"
}
let proxy = new Proxy(person,{
    get:function (target,property) {
    // 判断当前的key是否在对应的对象上,也就是查询对象上有没有要查的这个key
        if(property in target){
        ///如果有就返回这个值
            return target[property]
        }else{
        //没有则抛出错误
            throw new ReferenceError("Property \"" + property + "\" does not exist.");
        }
    }
})
console.log(proxy.name)// 小明
console.log(proxy.age)// 19岁
//console.log(proxy.aaa) 报错

 get方法内部有三个参数 第一个target表示接受对象,第二个是获取的key,第三个表示操作对象receiver(不常用)

5、set方法

set方法用来拦截某个属性的赋值操作

比如假定Person对象有一个age属性,该属性应该是一个不大于200的整数,那么可以使用Proxy保证age的属性值符合要求

let validator = {
    set : function (obj,prop,value) {
        //isInteger 整数
        if(!Number.isInteger(value)){
            throw new TypeError('The age is not an integer');
        }
        if(value > 200){
            throw new RangeError('The age seems invalid');
        }
        obj[prop] = value;
    }
}
let person = new Proxy({},validator);
console.log(person.age = 100);//100
console.log(person.age = 400);//报错

set方法一共有4个参数,第一个参数是接受的对象,第二个参数是设置的key,第三个是设置值,第四个参数是操作对象receiver(不常用)

6、apply 方法    **********?????

方法拦截函数的调用、call和apply操作

var twice = {
    apply(target, ctx, args) {
        // Reflect.apply(...arguments)返回是对参数的累加结果
        return Reflect.apply(...arguments) * 2;
    }
};
function sum(left, right) {
    // 累加
    return left + right;
};
var proxy = new Proxy(sum, twice);
proxy(1, 2) // 6
proxy.call(null, 5, 6) // 22
proxy.apply(null, [7, 8]) // 30

7、construct方法

construct方法用于拦截new命令

var p = new Proxy(function() {}, {
    construct: function(target, args) {
        console.log('called: ' + args.join(', '));
        return { value: args[0] * 10 };
    }
});
console.log(new p(1).value)

construct方法返回的必须是一个对象,否则会报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值