ES6 의 Proxy,Reflect 및 Vue 3.0 의 응용 원리

Vue 3.0 에서 Even You 는 Proxy 대신 Object.defineProperty 을 사용 해 데이터 응답 식 을 만 들 겠 다 고 밝 혔 다.Object.defineProperty 에 대해 잘 알 고 있 습 니 다.이전에 도 관련 Vue 양 방향 바 인 딩 원리(2)방문 기 속성 define Property()와 게시/구독 모드 를 쓴 적 이 있 습 니 다.
우리 도 Object.defineProperty 을 사용 하 는 약점 을 알 게 되 었 다.
  • Object.defineProperty 감청 은 대상 의 속성 이다.대상 이 비교적 복잡 하면 그의 속성 을 하나하나 심층 적 으로 옮 겨 다 니 며 감청 을 실현 해 야 한다.소모 성능
  • Object.defineProperty 은 배열 의 변 화 를 감청 할 수 없어 Vue 는 배열 에 추가 적 인 hack 를 할 수 밖 에 없 었 다.

  • 그 에 비해 Proxy 이 더 강하 다.그 다음 에 우 리 는 그 를 알 아 보 자.
    참고 자료:
  • MDN-Proxy
  • MDN-Reflect
  • 면접 관:쌍방 향 귀속 프 록 시가 defineproperty 보다 우열 을 실현 하 는 것 은 어 떻 습 니까?

  • 프 록 시 프로필
    Proxy 대상 은 기본 작업 의 사용자 정의 행동(예 를 들 어 속성 찾기,할당,매 거 진,함수 호출 등)을 정의 하 는 데 사 용 됩 니 다.사용 방법 은 다음 과 같다.
    //   
    let p = new Proxy(target, handler);
    //   
    let p = {a: 1};
    let proxyP = new Proxy(p, {
    	get() {
    		//   proxyP           
    	},
    	set() {
    		//   proxyP           
    	}
    })
    

    위의 코드 중:
  • target:프 록 시 로 포 장 된 대상(원생 배열,함수,심지어 다른 에이전트 포함).
  • handler:하나의 대상,그 속성 은 하나의 작업 을 수행 할 때 대리 의 행 위 를 정의 하 는 함수 입 니 다.
  • p/proxyP:대 리 된 새로운 대상 입 니 다.target 의 모든 속성 과 방법 을 가지 고 있 습 니 다.다만 행동 과 결 과 는 handler 에서 정의 합 니 다.
  • 여기 서 중요 한 것 은 handler:handler 자체 가 ES6 의 새로운 디자인 의 대상 이다.그 역할 은 대리 대상 을 사용자 정의 하 는 각종 대리 작업 이다.그 자체 에 모두 13 가지 방법 이 있 는데 모든 방법 이 하나의 조작 을 대리 할 수 있 고 자주 사용 하 는 몇 가지 방법 은 다음 과 같다.
    //                        ,      Object.defineProperty(proxy, "foo", {})  。
    handler.defineProperty()
    
    //                      ,      "foo" in proxy  。
    handler.has()
    
    //                   ,      proxy.foo  。
    handler.get()
    
    //                    ,      proxy.foo = 1  。
    handler.set()
    
    //                   ,      delete proxy.foo  。
    handler.deleteProperty()
    
    //                    ,      Object.getOwnPropertyNames(proxy)  。
    handler.ownKeys()
    
    //                        ,      proxy()  。
    handler.apply()
    
    //                             ,     new proxy()  。
    handler.construct()
    

    프 록 시가 프 록 시 모드 프 록 시 에 대한 역할 은 주로 세 가지 측면 에 나타난다.
  • 외부 대상 방문 차단 및 감시
  • 함수 나 클래스 의 복잡 도 를 낮 춘
  • 복잡 한 조작 전에 조작 을 검증 하거나 필요 한 자원 을 관리 하 는
  • Proxy Vue 3.0 에서 의 응용 원리
    위 에서 이미 Object.defineProperty 의 열 세 를 말 했다.상응하는 Proxy 의 우 세 는 매우 뚜렷 하 다.
  • 프 록 시 는 속성 이 아 닌 대상 을 직접 감청 할 수 있 습 니 다
  • Proxy 는 배열 의 변 화 를 직접 감청 할 수 있 습 니 다
  • 프 록 시 는 13 개의 차단 방법 이 있어 기능 이 더욱 강하 다.

  • 프 록 시의 약점:호환성 문제 가 있 고 poly fill 로 평평 하 게 갈 수 없 기 때문에 Vue 는 3.0 버 전이 되 어야 프 록 시 로 다시 쓸 수 있 습 니 다.
    간단 한 예:
    const input = document.getElementById('input');
    const p = document.getElementById('p');
    const obj = {};
    
    const newObj = new Proxy(obj, {
      get: function(target, key, receiver) {
        console.log(`getting ${key}!`);
        return Reflect.get(target, key, receiver);
      },
      set: function(target, key, value, receiver) {
        console.log(target, key, value, receiver);
        if (key === 'text') {
          input.value = value;
          p.innerHTML = value;
        }
        return Reflect.set(target, key, value, receiver);
      },
    });
    
    input.addEventListener('keyup', function(e) {
      newObj.text = e.target.value;
    });
    

    Reflect
    Reflect 는 내 장 된 대상 으로 자바 스 크 립 트 작업 을 차단 하 는 방법 을 제공 합 니 다.이 방법 들 은 프로세서 대상 의 방법 과 같다.Reflect 는 함수 대상 이 아니 기 때문에 구성 할 수 없습니다(즉,new Reflect).Reflect 대상 의 방법 은 Proxy 대상 의 방법 과 일일이 대응 하여 Proxy 대상 의 방법 이 라면 Reflect 대상 에서 대응 하 는 방법 을 찾 을 수 있다.이로써 Proxy 대상 이 대응 하 는 Reflect 방법 을 편리 하 게 호출 하여 기본 행 위 를 완성 하고 수정 행위 의 기초 로 삼 을 수 있다.즉,Proxy 이 기본 행 위 를 어떻게 수정 하 든 Reflect 에서 기본 행 위 를 얻 을 수 있다 는 것 이다.
    즉,Reflect.fn 은 handler 의 fn 의 기본 행동 을 나타 낸다.
    여기 서 우 리 는 두 단락 의 코드 를 본다.
    //    get/set    log  ,       
    var obj = new Proxy({}, {
      get: function (target, key, receiver) {
        console.log(`getting ${key}!`);
        //     console ,get         
        //     Reflect.get      ,         ,    undefined
        return Reflect.get(target, key, receiver);
      },
      set: function (target, key, value, receiver) {
        console.log(`setting ${key}!`);
        return Reflect.set(target, key, value, receiver);
      }
    });
    
    //          set        ,set       log,    
    var obj = new Proxy({}, {
      set: function(target, name, value, receiver) {
        var success = Reflect.set(target,name, value, receiver);
        if (success) {
          console.log('property ' + name + ' on ' + target + ' set to ' + value);
        }
        return success;
      }
    });
    

    좋은 웹페이지 즐겨찾기