이 글은 es6의 에이전트에 대한 자세한 소개(코드 예시)를 담고 있습니다. 필요한 친구들이 참고할 수 있기를 바랍니다.
에이전시는 에이전트에게 귀하를 대신하여 무언가를 해달라고 요청하는 것을 의미하지만, 귀하와는 달리 에이전트는 자신만의 행동을 가질 수 있으며 심지어 기대와는 반대로 행동할 수도 있습니다.
은 속성 이름을 갖는 공통 객체 출처를 선언합니다.
let origin={ name: 'origin' }
프록시 객체를 선언합니다
let proxy=new Proxy(origin, { get: (target, key)=>target[key]+" from proxy", set: (target, key, value)=>target[key]="set by proxy "+value })
이때 origin
과 proxy
가 출력됩니다. proxy
에는 origin
origin
和proxy
,可以发现,proxy
拥有和origin
一样的name
属性
console.log(origin) // {name: 'origin'} console.log(proxy) // Proxy {name: 'origin'}
为origin
添加age
属性,再输出,可以发现,origin
和proxy
都拥有了age
属性
origin.age=1 console.log(origin) // {name: 'origin', age: '1'} console.log(proxy) // Proxy {name: 'origin', age '1'}
那就是代理吗,当然不是,我们尝试为proxy
添加属性
proxy.x=1 console.log(origin) // {name: 'origin', age: '1', x:'set by proxy 1'} console.log(proxy) // Proxy {name: 'origin', age '1'}
可以发现,虽然origin
和proxy
都拥有了x
属性,但是并不是我们赋值的1
,而是多了set by proxy
几个字符串,很明显,这里是执行了初始化proxy
时传入的第二个对象的set
方法
那如果我们get
呢
console.log(proxy.x) // set by proxy 1 console.log(proxy.x) // set by proxy 1 from proxy
现在很清楚了,proxy
就是origin
的代理,所有在proxy
上的操作都会同步到origin
上,而对origin
的操作却不会同步到proxy
上,而且proxy
还有自己的行为。
可以这么想,proxy
就是origin
的秘书,所有的事务处理都要提交给秘书,秘书有自己的办事准则,可以直接提交给老板,也可以拒绝提交,或者添加一些其他的行为再提交。那这个秘书到底能代理老板做哪些事呢?
语法
let p = new Proxy(target, handler);
初始化一个代理需要有两个参数
target
:代理目标
handle
:陷阱,是一个对象,我们的操作就像一只逃跑的动物,如果猎人在所有可以逃跑的路上全部放满了陷阱,那我们总是会落入一起一个的。本质就是一个对象,键描述我们的操作,值是函数,描述我们的行为,一共有13
种陷阱。
set
:设置属性语法:
set(target, key, value)
target
: 代理对象
key: 设置的属性
value
: 设置的属性值
栗子:
let origin={} let proxy=new Proxy(origin,{ set:(target, key, value)=>{ if(value>5)target[key]=value+10000 } }) proxy.x=1 proxy.y=10 console.log(proxy) // Proxy {y: 10010} console.log(origin) // {y: 10010}
说明:
上面我们放置了一个set
陷阱,当我们做set
操作的时候,就会被捕捉到,我们判断value
是否大于5
,如果不大于5
我们就不会做任何东西,但是如果大于5
,就会给做赋值操作,并且还将他加上了10000
。上面的栗子就相当于一个拦截器了。
get:访问属性
语法:
get(target, key)
target
: 代理对象
key: 访问的属性
栗子:
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ get:(target, key)=>{ if(key==='x')return 'no' return target[key] } }) console.log(proxy.x) // 'no' console.log(proxy.y) // 2
deleteProperty:删除属性
语法:
deleteProperty(target, key)
target
: 代理对象
key: 要删除的属性
栗子:
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ deleteProperty:(target, key)=>{ if(key==='x')return delete target[key] } }) delete proxy.x delete proxy.y console.log(proxy) // {x:1}
has:判断是否包含某属性
语法:
has(target, key)
target
: 代理对象
key: 要判断的属性
栗子:
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ has:(target, key)=>{ if(key==='x')return false return true } }) console.log('x' in proxy) // false console.log('y' in proxy) // true
ownKeys
:获取自身属性值语法:
ownKeys(target)
target
: 代理对象
栗子:
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ ownKeys:(target)=>{ return ['y'] } }) console.log(Object.getOwnPropertyNames(proxy)) // ['y']
getPrototypeOf
:获取prototype
语法:
getPrototypeOf(target)
target
: 代理对象
栗子
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ getPrototypeOf:(target)=>{ return null } }) console.log(Object.getPrototypeOf(p)) // null
setPrototypeOf
:设置prototype
语法:
setPrototypeOf(target, prototype)
target
: 代理对象
prototype
: 要设置的prototype
栗子
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ setPrototypeOf:(target, prototype)=>{ throw 'no' } }) Object.setPrototypeOf(proxy, {}) // Uncaught no
defineProperty
:设置属性描述语法:
defineProperty(target, prop, descriptor)
target
: 代理对象
prop
: 要设置描述的属性
descriptor
: 描述
栗子
let origin={} let proxy=new Proxy(origin,{ defineProperty:(target, prop, descriptor)=>{ throw 'no' } }) Object.defineProperty(proxy, 'x', {configurable: true}) // Uncaught no
getOwnPropertyDescriptor
getOwnPropertyDescriptor(target, prop)
age
를 에 추가하는 것과 동일한 <code>name
속성이 있음을 알 수 있습니다. >origin 속성을 입력하고 출력하면 origin
과 proxy
모두에 age
속성이 있는 것을 확인할 수 있습니다let origin={} let proxy=new Proxy(origin,{ getOwnPropertyDescriptor:(target, prop)=>{ throw 'no' } }) Object.getOwnPropertyDescriptor(proxy, 'x') // Uncaught no
proxy
에
isExtensible(target)
origin
과 proxy
모두 x 속성은 그렇지 않습니다. 우리가 할당한 1
이 아니라 프록시에 의해 설정
된 여러 문자열이 분명히 프록시 입력된 두 번째 개체의 set
메서드get
🎜let origin={} let proxy=new Proxy(origin,{ isExtensible:(target)=>{ return false } }) console.log(Object.isExtensible(proxy)); // false
프록시는<code>origin
의 프록시입니다. proxy
에 대한 모든 작업은 origin
에 동기화되지만 origin
에 대한 작업은 >는 그렇지 않습니다. 프록시
와 동기화되며 프록시
에도 자체 동작이 있습니다. 🎜🎜 이렇게 생각하시면 됩니다. proxy
는 origin
의 비서입니다. 모든 거래는 비서에게 제출되어야 하며, 비서는 자신만의 업무 규칙을 가지고 있습니다. 제출을 거부하거나 제출하기 전에 다른 동작을 추가할 수 있습니다. 그렇다면 이 비서는 상사를 대신해 무엇을 할 수 있을까요? 🎜🎜Trap🎜🎜Syntax🎜preventExtensions(target)
target
: 프록시 대상 🎜🎜handle
: Trap은 객체이고 우리의 작업입니다. 도망가는 동물, 사냥꾼이 가능한 모든 탈출 경로에 함정을 설치하면 우리는 항상 그 중 하나에 빠지게 될 것입니다. 본질적으로 객체이며 키는 작업을 설명하고 값은 동작을 설명하는 함수입니다. 총 13
트랩이 있습니다. 🎜🎜0x003 set
: 속성 설정 🎜🎜구문: 🎜let origin={} let proxy=new Proxy(origin,{ preventExtensions:(target)=>{ return false; } }) console.log(Object.preventExtensions(proxy)); // Uncaught TypeError: 'preventExtensions' on proxy: trap returned falsish
target
: 프록시 객체 🎜🎜key: 속성 설정 🎜🎜값
: 설정 속성 값 🎜🎜 Chestnut: 🎜construct(target, argumentsList, newTarget)
set
트랩을 배치했습니다. set
작업을 수행하면 캡처됩니다. 값
이 5
보다 큰지 여부. 5
보다 크지 않으면 아무 작업도 수행하지 않지만 보다 큰 경우에는 >5
이면 할당 작업이 수행되고 10000
이 추가됩니다. 위의 밤은 인터셉터와 동일합니다. 🎜🎜get: 액세스 속성🎜🎜 구문: 🎜let Origin=function(){} let OriginProxy=new Proxy(Origin,{ construct: function(target, argumentsList, newTarget) { throw 'error' } }) new OriginProxy() // Uncaught error
target
: 프록시 객체 🎜🎜key: 액세스된 속성 🎜🎜Chestnut: 🎜apply(target, thisArg, argumentsList)
let origin=function(){} let proxy=new Proxy(origin,{ apply: function(target, thisArg, argumentsList) { throw 'error' } }) origin() // Uncaught error
target
: 프록시 개체 🎜🎜key: 삭제할 속성 🎜🎜Chestnuts: 🎜rrreee🎜has: 특정 속성이 포함되는지 확인 🎜🎜 구문: 🎜rrreee🎜target
: 프록시 객체🎜🎜key: 판단할 속성🎜🎜Chestnut: 🎜rrreee🎜 ownKeys
: 자체 속성 값 가져오기 🎜 🎜🎜🎜구문: 🎜rrreee
target
: 프록시 객체🎜 getPrototypeOf
: 프로토타입
가져오기🎜🎜🎜🎜구문: 🎜rrreee대상
: 프록시 객체🎜setPrototypeOf
: 프로토타입
설정🎜🎜🎜🎜구문: 🎜rrreeetarget
: 프록시 객체🎜🎜🎜prototype
: prototype🎜defineProperty
: 속성 설명 설정🎜🎜🎜🎜구문: 🎜rrreee 대상
: 프록시 객체🎜🎜🎜 prop
: 설명을 설정하는 속성🎜🎜🎜descriptor
: 설명🎜getOwnPropertyDescriptor
: 자체 속성 설명 가져오기🎜🎜🎜🎜구문: 🎜getOwnPropertyDescriptor(target, prop)
target
: 代理对象
prop
: 获取描述的属性
栗子
let origin={} let proxy=new Proxy(origin,{ getOwnPropertyDescriptor:(target, prop)=>{ throw 'no' } }) Object.getOwnPropertyDescriptor(proxy, 'x') // Uncaught no
isExtensible
:判断是否可扩展语法:
isExtensible(target)
target
: 代理对象
栗子
let origin={} let proxy=new Proxy(origin,{ isExtensible:(target)=>{ return false } }) console.log(Object.isExtensible(proxy)); // false
preventExtensions
:阻止扩展语法:
preventExtensions(target)
target
: 代理对象
栗子:
let origin={} let proxy=new Proxy(origin,{ preventExtensions:(target)=>{ return false; } }) console.log(Object.preventExtensions(proxy)); // Uncaught TypeError: 'preventExtensions' on proxy: trap returned falsish
construct
:构造语法:
construct(target, argumentsList, newTarget)
target
: 代理对象
argumentsList
: 参数列表
newTarget
: 新对象
栗子:
let Origin=function(){} let OriginProxy=new Proxy(Origin,{ construct: function(target, argumentsList, newTarget) { throw 'error' } }) new OriginProxy() // Uncaught error
apply
:调用语法:
apply(target, thisArg, argumentsList)
target: 代理对象
thisArg: 上下文
argumentsList: 参数列表
栗子:
let origin=function(){} let proxy=new Proxy(origin,{ apply: function(target, thisArg, argumentsList) { throw 'error' } }) origin() // Uncaught error
위 내용은 es6의 프록시에 대한 자세한 소개(코드 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!