전단 데이터 양 방향 연결 원리 이해 - Object. defineProperty ()

전단 데이터 양 방향 연결 원리 이해: Object. defineProperty ()
Object. defined Property 방법 은 대상 에 새로운 속성 을 직접 정의 하거나 대상 이 존재 하 는 속성 을 수정 하여 이 대상 을 되 돌려 줍 니 다.
문법
Object.defineProperty(obj, prop, descriptor)
인자:
obj 가 속성 을 정의 하거나 수정 하 는 대상;
prop 에서 정의 하거나 수정 할 속성 이름;
descriptor 속성 에 대한 설명;
반환 값
함 수 는 그 에 게 전 달 된 obj 대상 자 체 를 되 돌려 줍 니 다.
설명자 (descriptor) 설명
이 방법 은 개발 자가 대상 속성 에 대한 정확 한 정의 와 수정 을 허용 합 니 다.정상 적 인 할당 을 통 해 속성 을 추가 하여 구 축 된 속성 은 매 거 진 방법 (예 를 들 어 for... in 순환 또는 Object. keys 방법) 에 의 해 가 져 와 속성 값 이 외부 방법 에 의 해 변경 되 거나 삭 제 됩 니 다.한편, Object. defineProperty () 는 상기 설명 을 피 할 수 있 습 니 다. 기본적으로 Object. defineProperty () 를 통 해 추 가 된 속성 은 기본적으로 변경 할 수 없습니다.속성 설명 파라미터 (descriptor) 는 주로 두 부분 으로 구성 되 어 있 습 니 다. 데이터 설명자 (data descriptor) 와 방문 기 설명자 (accessor descriptor) 입 니 다.데이터 설명 자 는 속성 을 포함 하 는 값 이 며, 이 값 을 읽 을 수 있 거나 읽 을 수 없 는 대상 을 설명 합 니 다.접근 기 설명 자 는 이 속성 을 포함 하 는 getter - setter 방법의 대상 입 니 다.완전한 속성 설명 (descriptor) 은 반드시 이 두 가지 중 하나 여야 하 며, 둘 다 있어 서 는 안 된다.
데이터 설명자 와 방문 기 설명 자 는 각각 대상 입 니 다. 다음 키 쌍 을 포함해 야 합 니 다.
configurable 설정 한 속성의 설명자 만 수정 되 거나 delete 를 통 해 이 속성 을 삭제 해 야 할 때 configurable 속성 은 true 로 설정 합 니 다.기본 값 은 false 입 니 다.
enumerable 은 설정 한 속성 이 매 거 진 (예 를 들 어 for... in) 에 접근 할 때 만 true 로 설정 합 니 다.기본 값 은 false 입 니 다.
데이터 설명 자 는 다음 과 같은 선택 가능 한 키 쌍 을 포함 할 수 있 습 니 다:
value 는 속성의 값 을 설정 합 니 다. 모든 JavaScript 값 형식 (number, object, function 등 형식) 일 수 있 습 니 다.기본 값 은 undefined 입 니 다.
writable 은 속성의 값 만 할당 작업 이 수 정 될 때 true 로 설정 합 니 다.기본 값 은 false 입 니 다.
접근 기 설명 자 는 다음 과 같은 선택 가능 한 키 쌍 을 포함 할 수 있 습 니 다:
get 속성의 getter 방법, 속성 이 getter 방법 이 없 으 면 undefined 입 니 다.이 방법의 반환 은 속성의 값 이다.기본 값 은 undefined 입 니 다.
set 속성의 setter 방법, 속성 이 setter 방법 이 없 으 면 undefined 입 니 다.이 방법 은 속성의 새로운 값 으로 유일한 인 자 를 받 습 니 다.기본 값 은 undefined 입 니 다.
이 설명자 의 속성 은 필요 한 것 이 아니 라 원형 체인 에서 계승 한 속성 도 채 울 수 있다 는 것 을 명심 하 세 요.이 설명자 속성 이 기본 값 으로 채 워 질 수 있 도록 Object. prototype 을 미리 동결 하고 모든 설명자 속성 값 을 명 확 히 설정 하 며 Object. create (null) 를 사용 하여 빈 대상 을 가 져 오 는 등 방식 을 사용 할 수 있 습 니 다.
// using __proto__
var obj = {};
var descriptor = Object.create(null); // no inherited properties

//               
descriptor.value = 'static';
Object.defineProperty(obj, 'key', descriptor);

//            
Object.defineProperty(obj, 'key', {
  enumerable: false,
  configurable: false,
  writable: false,
  value: 'static'
});

//            
function withValue(value) {
  var d = withValue.d || (
    withValue.d = {
      enumerable: false,
      writable: false,
      configurable: false,
      value: null
    }
  );
  d.value = value;
  return d;
}
Object.defineProperty(obj, 'key', withValue('static'));

//  Object.freeze    ,                
(Object.freeze || Object)(Object.prototype);

사용 예시
속성 생 성
현재 대상 에 우리 가 설정 할 속성 이 존재 하지 않 는 다 면 Object. defineProperty () 는 방법 에 따라 대상 으로 설정 하여 새로운 속성 을 만 듭 니 다.설명자 파라미터 가 부족 하면 기본 값 으로 설 정 됩 니 다.모든 불 형 설명자 속성 은 기본적으로 false 로 설 정 됩 니 다.value, get, set 는 기본적으로 undefined 로 설 정 됩 니 다.get / set / value / writable 이 설정 되 지 않 은 속성 을 '원생 속성 (generic)' 이 라 고 부 르 며, 그의 설명자 (descriptor) 는 데이터 설명자 (data descriptor) 로 분류 된다.
var o = {}; //      

//               
Object.defineProperty(o, 'a', {
  value: 37,
  writable: true,
  enumerable: true,
  configurable: true
});
//  ”a”      o ,    37

//                
var bValue = 38;
Object.defineProperty(o, 'b', {
  get: function() { return bValue; },
  set: function(newValue) { bValue = newValue; },
  enumerable: true,
  configurable: true
});
o.b; // 38
//  ”b”      o ,    38。
//  o.b    bValue  ,  o.b     

//         、        
Object.defineProperty(o, 'conflict', {
  value: 0x9f91102,
  get: function() { return 0xdeadbeef; }
});
//        : value appears only in data descriptors, get appears only in accessor descriptors(value          ,get           )

속성 수정
어떤 속성 이 존재 할 때 Object. defineProperty () 는 대상 의 속성 설정 (configuration) 과 새로운 설정 값 에 따라 이 속성 을 수정 하려 고 시도 합 니 다.이 속성의 configurable 이 false 로 설정 되면 이 속성 은 수정 할 수 없습니다.속성의 configurable 을 false 로 설정 하면 데이터 설명자 와 방문 기 설명자 사이 에서 속성 설명 자 를 변환 할 수 없습니다.새 설정 의 속성 이 이 속성 과 다 르 고 이 속성의 configurable 이 false 로 설정 되면 형식 오류 (TypeError) 가 발생 합 니 다 (이전 텍스트 에서 말 한 특수 한 상황 제외).신 구 속성 이 완전히 같다 면 아무 일 도 일어나 지 않 을 것 이다.
쓰기 가능 기능 - writable
하나의 속성의 writable 이 false 로 설정 되면 이 속성 은 '쓸 수 없 는 (non - writable)' 이 됩 니 다.이 속성 은 다시 할당 할 수 없습니다.
var o = {}; //      

Object.defineProperty(o, 'a', {
  value: 37,
  writable: false
});

console.log(o.a); // 37
o.a = 25; //      
//           
console.log(o.a); //   37,      

상기 코드 에서 말 한 바 와 같이 '쓰기 불가 (non - writable)' 속성 을 다시 쓰 려 고 시도 하면 변경 되 지 않 고 오류 가 발생 하지 않 습 니 다.
매 거 진 기능 - enumerable
속성의 enumerable 값 정의 대상 의 속성 이 매 거 진 (for... in 순환 과 Object. keys () 에 나타 날 지 여부 입 니 다.
var o = {};
Object.defineProperty(o, 'a', {
  value: 1,
  enumerable: true
});
Object.defineProperty(o, 'b', {
 value: 2,
 enumerable: false
});
Object.defineProperty(o, 'c', {
  value: 3
}); //enumerable     false
o.d = 4; //           ,enumerable     true

for (var i in o) {
  console.log(i);
}
//   ’a’ ’d’

Object.keys(o); // ['a', 'd']

o.propertyIsEnumerable('a'); // true
o.propertyIsEnumerable('b'); // false
o.propertyIsEnumerable('c'); // false

설정 가능 기능 - configurable
속성의 configurable 값 은 한 대상 의 속성 이 delete 에서 삭 제 될 수 있 는 지 를 제어 하 는 동시에 이 속성 설명자 의 설정 이 바 뀔 수 있 는 지 를 제어 합 니 다 (앞에서 말 한 configurable 이 false 일 때 writable 이 true 일 경우 writable 을 false 로 변경 할 수 있 습 니 다).
var o = {};
Object.defineProperty(o, 'a', {
  get: function() { return 1; },
  configurable: false
});

Object.defineProperty(o, 'a', {
  configurable: true
}); //    
Object.defineProperty(o, 'a', {
  enumerable: true
}); //    
Object.defineProperty(o, 'a', {
  set: function() {}
}); //    (set      undefined)
Object.defineProperty(o, 'a', {
  get: function() { return 1; }
}); //    (    get       ,           )
Object.defineProperty(o, 'a', {
  value: 12
}); //    

console.log(o.a); // 1
delete o.a; //      
console.log(o.a); // 1

o. a 속성의 configurable 이 true 라면 오류 가 발생 하지 않 고 o. a 는 마지막 delete 작업 에서 삭 제 됩 니 다.
속성 추가 시 기본 값
설명자 특성 을 고려 한 기본 값 이 어떻게 적용 되 는 지 매우 중요 합 니 다.아래 예제 에서 보 듯 이 "." 기 호 를 간단하게 사용 하여 속성 을 설정 하 는 것 과 Object. defineProperty () 를 사용 하 는 것 은 큰 차이 가 있 습 니 다.
var o = {};

o.a = 1;
//   :
Object.defineProperty(o, 'a', {
  value: 1,
  writable: true,
  configurable: true,
  enumerable: true
});


//    ,
Object.defineProperty(o, 'a', { value: 1 });
//   :
Object.defineProperty(o, 'a', {
  value: 1,
  writable: false,
  configurable: false,
  enumerable: false
});

맞 춤 형 Setters 와 Getters
다음 예 는 '셀 프 압축 파일 (self - archiving)' 의 대상 을 어떻게 실현 하 는 지 보 여 준다.temperature 속성 이 설정 되면 archive 배열 은 로그 기록 을 추가 합 니 다.
function Archiver() {
  var temperature = null;
  var archive = [];

  Object.defineProperty(this, 'temperature', {
    get: function() {
      console.log('get!');
      return temperature;
    },
    set: function(value) {
      temperature = value;
      archive.push({ val: temperature });
    }
  });

  this.getArchive = function() { return archive; };
}

var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]

또는 아래 에 이렇게 쓰 는 것 도 같은 효과 입 니 다.
var pattern = {
    get: function () {
        return 'I always return this string, whatever you have assigned';
    },
    set: function () {
        this.myname = 'this is my name string';
    }
};


function TestDefineSetAndGet() {
    Object.defineProperty(this, 'myproperty', pattern);
}


var instance = new TestDefineSetAndGet();
instance.myproperty = 'test';
console.log(instance.myproperty);
// I always return this string, whatever you have assigned

console.log(instance.myname); // this is my name string

역자 주
Object. defineProperty () 방법 은 많은 현대 전단 프레임 워 크 (예 를 들 어 Vue. js, React. js) 에 의 해 데이터 양 방향 연결 의 실현 에 사 용 됩 니 다. 프레임 워 크 Model 층 에 data 를 설정 할 때 프레임 워 크 는 Object. defineProperty () 방법 으로 모든 데 이 터 를 연결 하고 데이터 가 변 하 는 동시에 가상 노드 를 수정 하여 페이지 의 Dom 구 조 를 최종 적 으로 수정 합 니 다.이 과정 에서 몇 가지 주의해 야 할 점 이 있다.
지연 변화
현대 프레임 워 크 는 밀 집 된 Dom 수정 작업 을 피하 기 위해 바 인 딩 된 데 이 터 를 수정 하면 아주 작은 (보통 1ms) setTimeout 지연 재 활용 변 화 를 설정 합 니 다.즉, 가상 노드 와 페이지 돔 트 리 의 변화 와 데이터 의 변화 사이 에 여가 가 존재 한 다 는 것 이다.이 점 을 알 게 된 개발 자 들 은 만약 에 우리 가 하나의 기능 을 실현 하고 싶다 면 만약 에 우리 가 현재 data 를 수정 하면 model 층 이 즉시 변화 하고 조작 가능 한 상태 에 있 기 를 기대 합 니 다. 이것 은 불가능 합 니 다.물론 많은 프레임 워 크 도 Vue 의 nextTick () 방법 등 많은 대응 방법 을 제공 했다.
배열 의 변화
먼저 Object. defineProperty () 가 배열 변화 에 대한 추적 상황 을 알 아 보 겠 습 니 다.
var a={};
bValue=1;
Object.defineProperty(a,"b",{
    set:function(value){
        bValue=value;
        console.log("setted");
    },
    get:function(){
        return bValue;
    }
});
a.b;//1
a.b=[];//setted
a.b=[1,2,3];//setted
a.b[1]=10;//   
a.b.push(4);//   
a.b.length=5;//   
a.b;//[1,10,3,4,undefined];

a. b 가 배열 로 설정 되 었 을 때 새로운 배열 대상 을 다시 할당 하지 않 으 면 배열 내부 의 수정 은 setter 방법 으로 실행 되 지 않 습 니 다.이 점 은 매우 중요 하 다. Object. defineProperty () 방법 을 바탕 으로 하 는 현대 전단 프레임 워 크 에서 이 루어 진 데이터 양 방향 연결 도 이러한 배열 변 화 를 식별 할 수 없 기 때문이다.따라서 첫 번 째, 데이터 의 양 방향 연결 을 촉발 하려 면 arr [1] = newValue 를 사용 하지 마 십시오.이런 문구 로 이 루어 진다.두 번 째, 프레임 워 크 도 여러 가지 방법 을 제공 하여 배열 의 양 방향 연결 을 실현 합 니 다. 예 를 들 어 Vue 프레임 워 크 가 제공 하 는 Vue. set () 함수 입 니 다.프레임 워 크 가 어떻게 배열 변화 에 대한 감 측 을 실현 하 는 지 에 대해 대부분 상황 에서 프레임 워 크 는 Array. prototype. push 방법 을 다시 쓰 고 새로운 배열 할당 데 이 터 를 생 성하 여 데이터 의 양 방향 연결 이 실 행 될 것 입 니 다.프레임 워 크 사용자 로 서 우리 가 알 아야 할 것 은 이렇게 실 현 된 배열 수정 이 더 많은 성능 을 소모 한 다 는 것 이다.
configurable 과 writable
원문 에서 특수 한 상황 을 묘사 한 적 이 있 습 니 다. configurable 이 false 일 때 우리 가 바 꿀 수 있 는 유일한 속성 은 true 로 설 정 된 writable 을 false 로 설정 하 는 것 입 니 다.이에 대해 번역 자 는 다음 과 같은 테스트 를 실시 했다 (아래 코드 는 Chrome 과 IE 에서 논증 을 실행 하고 출력 결 과 는 같다).
var a={};
Object.defineProperty(a,"o",{
    configurable:false,
    value:10,
    writable:true
});

console.log(a.o);//10
a.o=12;//   
console.log(a.o);//12

Object.defineProperty(a,"o",{
    configurable:false,
    value:14,
    writable:true
});
console.log(a.o);//14

Object.defineProperty(a,"o",{
    configurable:false,
    value:14,
    writable:false
});
a.o=16;//   
console.log(a.o);//14

//  
Object.defineProperty(a,"o",{
    configurable:false,
    value:16,
    writable:false
});

상기 코드 에서 결론 을 얻 을 수 있 습 니 다. 설명자 (descriptor) 가 데이터 설명자 (data descriptor) 인 경우: 1. "." 연산 자 를 사용 하여 속성 을 설정 하 는 값 은 영원히 잘못 보고 되 지 않 습 니 다. writable 이 false 일 때 만 유효 하지 않 습 니 다.2. writable 이 true 라면 configurable 이 false 든 아니 든 Object. defineProperty () 를 통 해 value 의 값 을 수정 할 수 있 습 니 다.이 를 통 해 각 브 라 우 저 운영 업 체 가 실현 하 는 Object. defineProperty () 와 표준 설명 은 configurable 의 정의 에 약간의 오차 가 있다 는 결론 을 얻 었 다.설명 자 는 데이터 설명자 의 시간 값 변경 여 부 는 writable 에 의 해 만 제 어 됩 니 다.
본문 에 대하 여
본 고 는 번역자 의 이 해 를 바탕 으로 Object. defineProperty () 방법의 원리 와 각종 사용 상황 을 상세 하 게 묘사 하여 데이터 의 양 방향 연결 원 리 를 이해 하 는 데 큰 도움 이 될 것 이다.그러나 독자 여러분 이 사용 가능 한 데이터 양 방향 연결 시스템 을 완전 하 게 실현 하려 면 이 를 개선 해 야 합 니 다.예 를 들 어 단일 구성 요소 의 대상 관리, 배열 이 수정 한 감청 방안, 밀집 형 수정의 최적화, 변화 후의 상태 관리 등 이다.
원본 주소:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
밤 을 새 는 것 은 쉽 지 않 으 니, 작가 에 게 술 을 한 잔 사 세 요!

좋은 웹페이지 즐겨찾기