고급 js: 내장 프록시 사용 사례

Using the right tool for solving a problem feels just great.



우선: 몇 가지 기능이 포함된 개체를 내보내고 있었습니다.

export default obj = {
  foo() { ... },
  goo() { ... },
  hoo() { ... },
  ...
  zoo() { ... },
}


그런 다음 이 요구 사항으로 끝납니다. obj의 모든 메서드는 isReady 조건을 확인해야 합니다. 이행되지 않으면 예외를 던지고 그렇지 않으면 유지하십시오.

그래서 PR은 다음과 같았습니다.

+ let isReady = false // set true at some point
+
export default obj = {
  foo() { 
+  if (!isReady) {
+    throw new Error(' ... ')
+  }
  ...
  },

  goo() { 
+  if (!isReady) {
+    throw new Error(' ... ')
+  }
  ...
  },

  hoo() { 
+  if (!isReady) {
+    throw new Error(' ... ')
+  }
  ...
  },

  ...

  zoo() { 
+  if (!isReady) {
+    throw new Error(' ... ')
+  }
  ...
  },
}


당신은 아이디어를 얻을

이 시점에서 우리는 "원래 개체를 래핑하고 다른 모든 것을 유지하면서 해당 속성에 대한 액세스를 보호할 방법이 없어서 너무 슬프다..."라고 생각했습니다.



...실제로 우리는 문제를 해결하는 내장 객체를 가지고 있습니다.

✨✨ 프록시 ✨✨



*정의: *

"create an object that can be used in place of the original object, but which may redefine fundamental Object operations like getting, setting, and defining properties"



기본적으로 우리가 찾고 있던 것입니다. 경비원.

=>

const isReadyProxyHandler = {
  get(target, prop) {
    if (typeof target[prop] === 'function') {
      return (...args) => {
        if (!isReady) {
          throw new Error(' ... ')
        }
        return target[prop].apply(this, args)
      };
    } else {
      return target[prop]
    }
  },
};

export default new Proxy(obj, isReadyProxyHandler)


상세히,
obj를 내보내는 대신 이제 obj를 래핑하는 프록시를 내보냅니다. 프록시 처리기를 정의하기만 하면 됩니다.

- export default obj
+ export default new Proxy(obj, handler)


이 경우 액세스( get() )를 트랩하고 함수인지 확인합니다(다른 상황에서는 속성을 확인해야 할 수도 있음).

  get(target, prop) {
    if (typeof target[prop] === 'function') {
      // function call
    } else {
      return target[prop]
    }


우리는 모든 "if() { throw } "블록을 하나의 중앙 위치로 옮겼습니다.

get(target, prop) {

+   if (!isReady) {
+     throw new Error(' ... ')
+   }
+   return target[prop].apply(this, args)

}



두가지:
  • 속성에 직접 액세스하거나( return target[prop] ) Reflect 이라는 다른 기본 제공 객체를 사용할 수 있습니다. 다른 게시물에서 이에 대해 더 깊이 파고들고 싶지 않습니다.

  • - return target[prop]
    + return Reflect.get(...arguments)
    


  • 예외가 발생할 수 있는 함수를 반환하고 있습니다. 우리는 즉시 예외를 발생시킬 수 없습니다.

  • 이걸 고려하세요:

    const a = { fn() { return 1 } }
    
    const pa = new Proxy(a, { 
      get(target, prop) {  
        throw new Error(' ... ')
      }
    })
    
    const { fn } = pa // 💥 Error
    


    하는 동안:

    const a = { fn() { return 1 } }
    
    const pa = new Proxy(a, { 
      get(target, prop) {  
        return (args) => {
          throw new Error(' ... ')
        }
      }
    })
    
    const { fn } = pa // ok
    fn() // 💥 BOOM
    



    Banner image by Storyset



    --
    읽어주셔서 감사합니다 💚.

    좋은 웹페이지 즐겨찾기