// Proxy
// 语法:let proxy = new Proxy(target, handler)
// target -- 表示所要拦截的目标对象
// handler -- 也是一个对象,用来定制拦截行为
let lv = {
brand:'prada',
price:9000
}
// ①、get 得到某对象属性值时预处理的方法,可以接收两个常用参数
// target:得到的目标值;
// key:目标的key值,相当于对象的属性
// receiver:一般都是指向proxy实例对象
// 注:如果一个对象属性不可配置(configurable:false)且不可写(writable:false),则proxy不能修改该属性,否则通过对象访问该属性会报错
lv = new Proxy(lv,{
// 拦截读取属性操作
get(target,key,receiver) {
console.log(target,'--->target') // {"brand":"prada","price":9000},
console.log(key,'--->key') // price
// console.log(receiver,'--->receiver') // lv proxy实例对象本身
if(target['brand'] == 'prada') {
if(target['price']>5000) {
return '无力支付'
} else {
return '可以,马上发货'
}
}
}
})
console.log(lv.price) // 无力支付
console.log('------------------------------')
// ②、set 用来拦截某个属性的赋值操作,可以接收四个参数
// target:目标值
// key:目标的key值
// value:要改变的值
// receiver:改变前的原始值,一般指 proxy实例对象本身
let arr = []
arr = new Proxy(arr,{
// 拦截写入的操作
set(target,key,value,receiver) {
console.log(target,'--->target') // []
console.log(key,'--->key') // 0
console.log(value,'--->value') // 11
console.log(receiver,'--->receiver') // [11] proxy实例对象本身
if(typeof value == 'number') {
target[key] = value
return true // 成功写入时要返回true
} else {
throw new TypeError('不能引入字符串类型的数据')
}
}
})
arr.push(11)
// arr.push('11') // Uncaught TypeError: 不能引入字符串类型的数据
console.log(arr.length) // 1
// ③、proxy实例可以作为其他对象的原型
let pro = new Proxy({},{
get(target,key) {
return 777
}
})
// pro对象是obj对象的原型,obj本身并没有name属性,所以根据原型链,会在pro对象上读取该属性,导致被拦截读取
let obj = Object.create(pro)
console.log(obj.name) // 777
console.log('-------------------------------')
// apply 拦截函数的调用、call和apply操作,可以接收三个参数
// target:目标对象
// ctx:目标对象的上下文对象 (this)
// arg:目标对象的参数数组
let fn = ()=> {
console.log('111')
}
fn = new Proxy(fn,{
apply(target,ctx,arg) {
console.log(target,'--->target')
console.log(ctx,'--->ctx')
console.log(arg,'--->arg')
return console.log('call拦截')
}
})
fn()
// Reflect.apply(...arguments) 直接调用 Reflect.apply也会被拦截
// Reflect.apply(fn, null, [9, 10])
console