JavaScript define Property 속성 납 치 를 어떻게 실현 합 니까?

머리말
define Property 는 vue 가 데이터 납 치 를 실현 하 는 핵심 으로 본 고 는 define Property 가 속성 납 치 를 어떻게 실현 하 는 지 조금씩 설명 한다.
사실 우리 의 일반적인 조작 대상 속성 방식 은 속성 을 증가 하거나 수정 할 때 모두 Object.defineProperty 를 사용 할 수 있 습 니 다.

let obj = {};
//     :  /      
obj.a = 1;
//    :
Object.defineProperty(o, "a", {
  value: 1,
  writable: true,
  configurable: true,
  enumerable: true
});
물론 예 사 롭 지 않 은 예,우 리 는 이렇게 놀 지 않 을 것 이다.너무 수다스럽다.
그러나 define Property 는 대상 의 속성 을 더욱 정확하게 추가 하거나 수정 할 수 있 습 니 다.
설명자
먼저 고유 명사:설명자.
사실은 define Property 의 세 번 째 매개 변수 로 대상 입 니 다.이 대상 의 속성 은 다음 과 같 습 니 다:
  • configurable 속성:설명 자 를 수정 할 수 있 습 니까?설명 자 를 다시 수정 할 수 있 습 니까?다른 속성
  • enumerable 속성:이 속성 을 매 거 할 수 없 는 것 은 a 속성 이
  • 까지 사용 할 수 있 는 지 여부 입 니 다.
  • writable 속성:속성 값 을 수정 할 수 있 습 니까?바로 obj.a 를 이렇게 수정 할 수 있 습 니까?=1
  • value 속성:이 속성의 값
  • get 속성:함수 입 니 다.이 속성 에 접근 할 때 함수 가 자동 으로 호출 되 고 함수 반환 값 은 이 속성의 값
  • 입 니 다.
  • set 속성:하나의 함수 입 니 다.이 속성 을 수정 할 때 함수 가 자동 으로 호출 되 고 함수 가 있 으 며 하나의 매개 변수 만 있 습 니 다.할당 의 새로운 값 은
  • 입 니 다.
    조심해!!!
  • 설명 부적 의 value 속성 writable 속성 과 get 속성 set 속성 은 서로 배척 하 는 관계 로
  • 만 존재 합 니 다.
  • 다른 속성 은 기본 값 이 모두 false 입 니 다.false 가 싫 으 면 설정 을 기억 하 세 요.자세히 말 하지 않 아 도 됩 니 다.
  • get 과 set 를 자세히 말 하 다.
  • get 속성:함수 입 니 다.이 속성 에 접근 할 때 함수 가 자동 으로 호출 되 고 함수 반환 값 은 이 속성의 값
  • 입 니 다.
  • set 속성:하나의 함수 입 니 다.이 속성 을 수정 할 때 함수 가 자동 으로 호출 되 고 함수 가 있 으 며 하나의 매개 변수 만 있 습 니 다.할당 의 새로운 값 은
  • 입 니 다.
    세 번 묵독 하고 외우다.
    get 과 set 의 예 를 써 서 이 해 를 보조 합 니 다.
    이 예 는 반드시 파악 해 야 한다.이해 한 후에 데이터 납치 의 정 수 를 기본적으로 파악 했다.
    
    let obj = {};
    
    let value = 1;
    Object.defineProperty(obj, "b", {
      get() {
        console.log("  b  ", value);
        return value;
      },
      set(newValue) {
        console.log("  b  ", newValue);
        value = newValue;
      }
    });
    //   get  ,get         
    // 1
    console.log(obj.b);
    //   set  ,value     2,  !!!,     ,        
    obj.b = 2;
    //   ,          ,      get  ,          ,        
    console.log(obj.b);
    
    여기에 구덩이 가 있 습 니 다.get 에 서 는 읽 기 동작 이 있 을 수 없습니다.그렇지 않 으 면 계속 순환 하기 때문에 get set 에 사용 하려 면 변 수 를 빌려 야 합 니 다.
    따라서 여기 서 변수 value 의 값 은 속성의 값 입 니 다.속성 을 수정 하려 면 value 의 값 을 수정 하면 됩 니 다.
    이 예 는 get,set 의 정 수 를 알 게 되 었 으 니 나 도 별로 차이 가 없다 고 생각한다.
    납치 대상 의 어떤 속성
    방금 예 를 들 어 납치 대상 의 임의의 속성 을 써 보 세 요.
    
    function observeKey(obj, key) {
      let value = obj[key];
      Object.defineProperty(obj, key, {
        get() {
          console.log("    ", value);
          return value;
        },
        set(newValue) {
          console.log("    ", newValue);
          value = newValue;
        }
      });
    }
    let obj = { a: 1 };
    observeKey(obj, "a");
    //   a,  get  
    console.log(obj.a);
    //   a,  set  
    obj.a = 1;
    
    납치 대상 의 모든 속성
    납치 대상 의 모든 속성 을 다시 시도 해 보 세 요.
    사실은 옮 겨 다 니 는 것 이다.
    
    function observeObj(obj) {
      for (let key in obj) {
        //      obj.hasOwnProperty      
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          observeKey(obj, key);
        }
      }
      return obj;
    }
    function observeKey(obj, key) {
      let value = obj[key];
      Object.defineProperty(obj, key, {
        get() {
          console.log("    ", value);
          return value;
        },
        set(newValue) {
          console.log("    ", newValue);
          value = newValue;
        }
      });
    }
    
    let obj = { a: 1, b: 2 };
    observeObj(obj);
    console.log(obj);
    //   a,  get  
    console.log(obj.a);
    //   a,  set  
    obj.a = 1;
    
    
    납치 대상 의 모든 속성-대상 유형의 속성 치 포함
    위의 결함 이 있 습 니 다.속성 값 이 대상 일 때 속성 값 을 납치 할 수 없습니다.예 를 들 어{a:1,c:{b:1}}
    간단 하 다
    
    function observeObj(obj) {
      //       ,         ,         
      if (typeof obj !== "object" || obj == null) {
        return;
      }
      for (let key in obj) {
        //      obj.hasOwnProperty      
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          observeKey(obj, key);
          //            ,          ,   
          observeObj(obj[key]);
        }
      }
      return obj;
    }
    function observeKey(obj, key) {
      let value = obj[key];
      Object.defineProperty(obj, key, {
        get() {
          console.log("    ", value);
          return value;
        },
        set(newValue) {
          console.log("    ", newValue);
          value = newValue;
        }
      });
    }
    
    let obj = { a: 1, b: 2, c: { name: "c" } };
    observeObj(obj);
    console.log(obj);
    //   a,  get  
    console.log(obj.a);
    //   a,  set  
    obj.a = 1;
    //   set  
    obj.c.name = "d";
    
    
    observeObj 라 는 함 수 는 납치 대상 의 추가 속성 을 증가 할 수 없고 납치 대상 의 기 존 속성 만 있 습 니 다.
    define Property 의 결함
  • 모니터링 대상 증가 속성
  • 모니터링 대상 삭제 속성
  • 납치 불가 배열 의 수정
  • 물론 수조 의 수정 은 다른 방식 으로 감 측 될 수 있 는데 그것 은 납 치 를 통 해 배열 방법 을 바 꾸 어 이 루어 진 것 이다. 이다.
    이상 의 결함 도 vue 에 왜$set/$delete 가 있 는 지,그리고 배열 에 대해 서 는 특정한 방법 만 사용 해 야 감지 할 수 있 습 니 다.
    
    let obj = { a: 1, b: [1, 2] };
    observeObj(obj);
    //     
    obj.c = 3;
    //     get  
    console.log(obj.c);
    //     set  
    obj.b.push(3);
    
    
    define Property 속성 마 운 트 가능
    사실은 options.data.name 에 접근 하면 options.name,전문 화 술 로 간략화 하여 data 의 속성 을 options 에 마 운 트 할 수 있 습 니 다.
    define Property 를 사용 하여 options 에 새로운 속성 을 추가 하 는 것 과 같 습 니 다.
    
    //        
    // options.data   source options   target
    function proxyKey(target, source, key) {
      Object.defineProperty(target, key, {
        //    source[key]     value,              
        get() {
          return source[key];
        },
        set(newValue) {
          if (newValue === source[key]) {
            return;
          }
          source[key] = newValue;
        }
      });
    }
    //     ,   
    function proxyObj(target, source) {
      for (let key in source) {
        //      obj.hasOwnProperty      
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          proxyKey(target, source, key);
        }
      }
    }
    let options = {
      data: { name: 1 }
    };
    proxyObj(options, options.data);
    // 1
    console.log(options.name);
    
    
    vue 의 속성 납치 와 마 운 트 속성 은 핵심 원리 차이 가 많 지 않 은 것 이 바로 위 에 있다.
    define Property 로그 도 쓸 수 있어 요.
    예 를 들 어 obj 에 속성 이 있 습 니 다.이 속성 값 은 자주 변 합 니 다.모든 변 화 된 값 을 기록 하려 면 로 그 를 만 들 수 있 습 니 다.
    
    let obj = { a: 1 };
    
    let log = [obj.a];
    
    let value = obj.a;
    Object.defineProperty(obj, "a", {
      get() {
        return value;
      },
      set(newValue) {
        if (newValue === value) {
          return;
        }
        value = newValue;
        log.push(newValue);
      }
    });
    
    obj.a = 2;
    obj.a = 3;
    obj.a = 4;
    // [1,2,3,4]
    console.log(log);
    
    통용 되 는 것 은 하나의 종 류 를 추출 하여 특정한 값 의 변 화 를 전문 적 으로 기록 할 수 있다.
    
    class Archiver {
      constructor() {
        let value = null;
        this.archive = [];
        Object.defineProperty(this, "a", {
          get() {
            return value;
          },
          set(newValue) {
            if (newValue === value) {
              return;
            }
            value = newValue;
            this.archive.push(newValue);
          }
        });
      }
    }
    let archiver = new Archiver();
    archiver.a = 1;
    archiver.a = 2;
    // [1,2]
    console.log(archiver.archive);
    
    인용 하 다.
    MDN 의 define Property
    총결산
    자 바스 크 립 트 define Property 가 속성 납 치 를 어떻게 실현 하 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 define Property 속성 납치 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기