ES6의 Proxy와 Reflect는 도대체 어떤 귀신입니까?

5855 단어
1. Proxy 1, 개요 Proxy는 영어로 "프록시"를 의미합니다.대리란 당신이 어떤 물건을 얻거나 그것을 조작하는 중간 매개체이지 이 대상에 직접적으로 작용하는 것이 아니다.이것은 우리가 인터넷에서 물건을 사는 것과 유사하기 때문에 제조업체에 직접 구매하는 것이 아니라 인터넷 상점 플랫폼에서 구매해야 한다.Proxy 대상은 바로 이런 매개체입니다. 이 대상을 조작하려면 이 매개체의 동의를 받아야 합니다.사용 방법: let p = new Proxy(target, habdler),target:Proxy로 포장된 목표 대상(수조 대상, 함수 또는 다른 에이전트일 수 있음);handler: 필터 프록시 동작을 차단하는 대상
let obj = {
  name: " ",
  age:28
}
  
let p = new Proxy(obj, {
  get: function (target, key) {
    if (key in target) {
      return target[key]
    } else {
      console.log(" ");
    }
  },
  set: function (target, key, value) {
    if (key == "age" & value < 1) {
      console.log(" ");
    } else {
      target[key] = value;
    }
  }
});
p.age = -1;
p.age = 22;
console.log(p.age);
console.log(p.name);
//  
// 22
//  

2. 실례 방법은 위 코드에서 set과 get 두 가지 실례 방법을 제외하고 Proxy 대상의 실례 방법은 다음과 같다.
메서드
묘사
handler.apply()
함수로 호출되는 Proxy 인스턴스 차단
handler.construct()
함수로 호출되는 Proxy 인스턴스 차단
handler.defineProperty()
Object 차단.defineProperty() 작업
handler.deleteProperty()
Proxy 인스턴스 제거 속성 작업 차단
handler.get()
읽기 속성 차단
handler.set()
속성 할당 작업 차단
handler.getOwnPropertyDescriptor()
Object 차단.getOwnPropertyDescriptor() 작업
handler.getPrototypeOf()
원형 대상을 가져오는 동작을 차단합니다
handler.has()
속성 검색 작업 차단
handler.isExtensible()
Object 차단.isExtensible() 작업
handler.ownKeys()
Object 차단.getOwnPropertyDescriptor() 작업
handler.preventExtension()
Object 차단().preventExtension() 작업
handler.setPrototypeOf()
Object 차단.setPrototypeOf() 작업
Proxy.revocable()
취소 가능한 Proxy 인스턴스 만들기
2. Reflect 1, 개요는 Proxy와 같고 ES6도 새로 추가되었습니다.그것은 일부 방법을 새로 추가했는데, 이런 방법들은 일부 조작을 더욱 규범화하고 편리하게 할 수 있다.대상은 다음과 같은 특징이 있다. (1).Proxy 객체에 프록시 메서드가 있는 한 Reflect 객체는 모두 정적 메서드로 존재합니다.이 방법들은 Proxy가 기본 행동을 어떻게 수정하든지 간에 Reflect에 대응하는 방법으로 기본 행동을 가져올 수 있습니다.(2).새로운 방법은 기존의 몇 가지 방법과 기능이 중복되고 새로운 방법은 기존의 방법, 예를 들어 Reflect를 대체할 것이다.getPrototypeOf (), Object 대상은 같은 방법과 기능도 같지만 getPrototypeOf () 방법을 Reflect에 이식하는 것이 합리적입니다.기존의 명령식 조작을 대체하는 새로운 방법도 있다. 예를 들어 속성이 존재하는지 아닌지를 판단하는 in 명령을 Reflect로 사용한다.has () 방법으로 대체합니다.2. 실례 방법
메서드
묘사
handler.apply()
지정한 매개 변수 목록을 통해 목표 함수에 대한 호출을 시작합니다
handler.construct()
이 방법은 new 조작부호 구조 함수와 비슷하며 new target (...args) 을 실행하는 것과 같다
handler.defineProperty()
메소드 기능은 Object와 유사합니다.defineProperty() 메서드
handler.deleteProperty()
기능은 delete 연산자와 유사합니다
handler.get()
객체에서 지정된 속성 값 가져오기
handler.set()
지정한 대상의 속성을 설정합니다. 예를 들어 대상에 새로운 속성을 추가하거나 기존 속성의 값을 수정합니다.
handler.getOwnPropertyDescriptor()
기능은 Object와 유사합니다.getOwnPropertyDescriptor()
handler.getPrototypeOf()
객체의 원형 객체 가져오기
handler.has()
객체의 원형 객체 가져오기
handler.isExtensible()
하나의 대상이 확장 가능한지 아닌지를 판단하다
handler.ownKeys()
매개 변수 대상이 있는 속성 이름을 포함하는 그룹을 되돌려줍니다.
handler.preventExtension()
객체를 확장 불가능으로 설정
handler.setPrototypeOf()
지정된 객체의 원형 객체 설정
3. 응용 실례 1, 조작 노드(두 개의 서로 다른 요소의 속성이나 클래스 이름 전환)
let view = new Proxy({
  selected: null
},
{
  set: function(obj, prop, newval) {
    let oldval = obj[prop];

    if (prop === 'selected') {
      if (oldval) {
        oldval.setAttribute('aria-selected', 'false');
      }
      if (newval) {
        newval.setAttribute('aria-selected', 'true');
      }
    }

    // The default behavior to store the value
    obj[prop] = newval;
  }
});

let i1 = view.selected = document.getElementById('item-1');
console.log(i1.getAttribute('aria-selected')); // 'true'

let i2 = view.selected = document.getElementById('item-2');
console.log(i1.getAttribute('aria-selected')); // 'false'
console.log(i2.getAttribute('aria-selected')); // 'true'

2. 대상의 다중 계승
var obj1 = {
    name: "obj-1",
    foo() {
        console.log( "obj1.foo:", this.name );
    }
},
obj2 = {
    name: "obj-2",
    foo() {
        console.log( "obj2.foo:", this.name );
    },
    bar() {
        console.log( "obj2.bar:", this.name );
    }
},
handlers = {
    get(target,key,context) {
        if (Reflect.has( target, key )) {
            return Reflect.get(target, key, context);
        }
        else {
            for (var P of target[Symbol.for( "[[Prototype]]" )]) {
                if (Reflect.has( P, key )) {
                    return Reflect.get(P, key, context);
                }
            }
        }
    }
},
obj3 = new Proxy({
    name: "obj-3",
    baz() {
        this.foo();
        this.bar();
    }
},handlers);

obj3[Symbol.for("[[Prototype]]")] = [obj1, obj2];
obj3.baz();
//obj1.foo:obj-3
//obj2.bar:obj-3

만약에 우리가 대상 간의 단일 계승을 실현하려면, 예를 들어obj3이obj1에서 계승하려면 Object를 사용할 수 있다.setPrototypeOf 방법이지만 다중 계승을 실현할 수 없습니다.그래서 위 코드에 사용자 정의 속성 Symbol을 사용했습니다.for([[Prototype])는 상속할 여러 상위 객체를 나타냅니다.그리고 Proxy로 모든 obj3의 get 요청을 차단하고 obj3에 해당하는 속성이나 방법이 있는지 확인하며 Reflect를 사용합니다.has 방법, 있으면 직접 전송하기;없으면 부모 대상 목록을 훑어보고 부모 대상에서 해당하는 속성이나 방법이 있는지 하나하나 검사하고 있으면 호출합니다.만약 없다면 get은undefined로 돌아가는 것과 같다.논리는 여전히 매우 이해하기 쉽고 코드도 비교적 명확하기 때문에 너무 많은 해석이 필요 없을 것이다.
내 블로그를 찌르다

장별 목록


1. ES6에서 블록급 작용역은 무엇입니까?어디에 활용합니까?2. ES6에서 구조 해제 값을 사용하면 우리에게 무엇을 가져다 줄 수 있습니까?3, ES6 문자열 확장은 어떻게 증가했습니까?4. ES6의 정규 확장성은 무엇입니까?5. ES6 수치의 확장성은 무엇입니까?6, ES6 함수 확장(화살표 함수) 7, ES6 배열은 우리에게 어떤 조작의 편리함을 가져다 줍니까?8, ES6 객체 확장 9, Symbol 데이터 유형은 ES6에서 어떤 역할을 합니까?10. 맵과 Set 두 데이터 구조가 ES6의 역할 11, ES6의 Proxy와 Reflect는 도대체 무엇입니까?12. Promise에서 시작하여 비동기 조작에 들어가는 여행 13, ES6 교체기(Iterator)와 for...of 순환 사용 방법 14, ES6 비동기 진급 2단계:Generator 함수 15, JavaScript 비동기 조작 진급 3단계:async 함수 16, ES6 구조 함수 문법 설탕:class류

좋은 웹페이지 즐겨찾기