>웹 프론트엔드 >JS 튜토리얼 >es6의 프록시에 대한 자세한 소개(코드 예)

es6의 프록시에 대한 자세한 소개(코드 예)

不言
不言앞으로
2018-11-17 15:57:401895검색

이 글은 es6의 에이전트에 대한 자세한 소개(코드 예시)를 담고 있습니다. 필요한 친구들이 참고할 수 있기를 바랍니다.

개요

에이전시는 에이전트에게 귀하를 대신하여 무언가를 해달라고 요청하는 것을 의미하지만, 귀하와는 달리 에이전트는 자신만의 행동을 가질 수 있으며 심지어 기대와는 반대로 행동할 수도 있습니다.

Chestnut

은 속성 이름을 갖는 공통 객체 출처를 선언합니다.

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
})

이때 originproxy가 출력됩니다. proxy에는 originoriginproxy,可以发现,proxy拥有和origin一样的name属性

console.log(origin) // {name: 'origin'}
console.log(proxy) // Proxy {name: 'origin'}

origin添加age属性,再输出,可以发现,originproxy都拥有了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'}

可以发现,虽然originproxy都拥有了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种陷阱。

0x003 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 속성을 ​​입력하고 출력하면 originproxy 모두에 age 속성이 있는 것을 확인할 수 있습니다
    let origin={}
    let proxy=new Proxy(origin,{
        getOwnPropertyDescriptor:(target, prop)=>{
            throw 'no'
        }
    })
    Object.getOwnPropertyDescriptor(proxy, 'x') //  Uncaught no
  • 그렇죠 물론 그렇지 않습니까? proxy

    isExtensible(target)
    속성을 추가해 보면 originproxy 모두 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에 대한 작업은 >는 그렇지 않습니다. 프록시와 동기화되며 프록시에도 자체 동작이 있습니다. 🎜🎜 이렇게 생각하시면 됩니다. proxyorigin의 비서입니다. 모든 거래는 비서에게 제출되어야 하며, 비서는 자신만의 업무 규칙을 가지고 있습니다. 제출을 거부하거나 제출하기 전에 다른 동작을 추가할 수 있습니다. 그렇다면 이 비서는 상사를 대신해 무엇을 할 수 있을까요? 🎜🎜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)
    🎜 deleteProperty: 삭제 속성🎜🎜 구문: 🎜
    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: 프록시 객체🎜
    🎜🎜Chestnut: 🎜rrreee🎜getPrototypeOf: 프로토타입 가져오기🎜🎜🎜🎜구문: ​​🎜rrreee
      🎜🎜대상: 프록시 객체🎜
    🎜 🎜 밤나무 🎜rrreee🎜setPrototypeOf: 프로토타입 설정🎜🎜🎜🎜구문: ​​🎜rrreee
      🎜🎜target: 프록시 객체🎜🎜🎜prototype: prototype🎜
    🎜🎜Chestnut🎜rrreee🎜defineProperty : 속성 설명 설정🎜🎜🎜🎜구문: ​​🎜rrreee
      🎜🎜대상: 프록시 객체🎜🎜🎜 prop: 설명을 설정하는 속성🎜🎜🎜descriptor: 설명🎜
    🎜🎜Chestnut🎜rrreee ul> 🎜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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제