























Proxy主要用于改变对象属性的默认访问行为,在目标对象之前架设一层"拦截",外界对该属性的访问,都需先通过这一层拦截,因此提供了一层机制,可对外界的访问进行过滤和改写。
/*
* target: 目标对象
* handler: 配置对象,用来定义拦截的行为
* oproxy: Proxy构造器的实例
*/
const obj = {}
const handler = {
get(target, key,receiver){ // 拦截对象属性的读取
console.log('get')
return Reflect.get(target, key,receiver)
},
set(target, key, value, receiver){ // 拦截对象属性的设置
console.log('set')
return Reflect.set(target, key, value, receiver)
},
has(target, key){ // 拦截propKey in proxy 操作
console.log('has')
return Reflect.has(target, key)
},
deleteProperty(target, key){// 拦截delete proxy[propKey] 操作 返回一个布尔值
console.log('deleteProperty')
return Reflect.deleteProperty(target, key)
},
defineProperty(target, key, desc){ // 拦截Object.defineProperty(proxy, key, desc)/Object.defineProperties(proxy,decs) 返回一个布尔值
return Reflect.defineProperty(target, key,desc)
},
construct(target, args){ // 拦截 proxy实例作为构造函数实例化的操作,比如 new proxy(...args)
console.log('construct')
return Reflect.construct(target, args)
},
ownKeys(target){ //getOwnPropertyNames(proxy) / getOwnPropertySymbols(proxy)/for...in/Object.keys(proxy),返回一个数组。Object.keys,而Object.keys()返回结果仅包括目标对象可遍历的属性
console.log('ownKeys')
return Reflect.ownKeys(target)
},
getOwnPropertyDescriptor(target,key){//拦截Object.getOwnPropertyDescriptor(), 返回属性的的描述对象
console.log('getOwnPropertyDescriptor')
return Reflect.getOwnPropertyDescriptor(target,key)
},
preventExtensions(target){ // 拦截Object.preventExtensions(proxy), 返回一个布尔值
console.log('preventExtensions')
return Reflect.preventExtensions(target)
},
getPrototypeOf(target){ // 拦截Object.getPrototyOf(proxy), 返回一个对象
console.log('getPrototypeOf')
return Reflect.getPrototypeOf(target)
},
setPrototypeOf(target, proto){// 拦截Object.setPrototyOf(proxy,proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
console.log('setPrototypeOf')
return Reflect.setPrototypeOf(target, proto)
},
apply(target,object ,args){//拦截proxy实例作为函数时的调用,比如proxy(...args)/proxy.call(object, ...args)/proxy.apply(...args)
console.log('apply')
return Reflect.apply(target, object ,args)
},
isExtensible(target){// 拦截Object.isExtensible(), 返回一个布尔值
console.log('isExtensible')
return Reflect.isExtensible(target)
}
}
const oproxy = new Proxy(obj, handler)
obj.a = 1
console.log(oproxy.a)//
Proxy代理的对象属性是外层的,如果需要属性值对象进行代理,可以通过递归设置代理。
设置内层属性递归代理
const obj = {
a: 1,
objb: {
c: 2
}
}
const handler = {
get(target, key, receiver){
console.log('get')
const value = target[key]
if(value !== 'null' && typeof value === 'object'){
return new Proxy(value, handler)
}
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver){
return Reflect.set(target, key, value, receiver)
}
}
const oproxy = new Proxy(obj, handler)
oproxy.objb.c
// 输出
// get
// get
// 2
Object.defineProperty()直接在对象定义新属性,或者修改对象上的现有属性,并返回该对象。
/*
* obj 要在其上定义或修改属性的对象
* prop 要定义或修改的属性的名称或者Symbol
* descriptor 定义或修改的属性描述符
*/
Object.defineProperty(obj, prop, descriptor)
描述符: 分为数据描述符和存取描述符,一个描述符只能是其中的一个,不能同时是两者。
共享属性: 1、configurable 表示可配置的,默认为false。当为true时,该属性的描述符才可以被改变,同时该属性可以被删除。
2、enumrable 表示可枚举的,默认为false。当为true时,该属性才会在对象枚举时枚举到。
数据描述符特有属性: 1、value 表示属性对应的值,默认为undefined 2、writable 表示属性是否可修改的,默认为false。只有值为true时,属性的值才可以被修改运算符修改成功。
const obj = {}
Object.defineProperty(obj, 'name', {
configurable: true,
enumrable: true,
value: 'jack',
writable: true
})
存取描述符特有属性: **1、get ** 当获取属性值的时候就会执行getter函数,该函数返回一个值, 默认为undefined 2、set 当设置属性值的时候就会执行setter函数
const obj = {}
Object.defineProperty(obj, 'name',{
configurable: true,
enumrable: true,
get(){
console.log('get--name')
return 'jack'
},
set(value){
console.log('set---name')
return value
}
})
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。