JavaScript 의 Object. defineProperty () 함수 이해 하기

7977 단어 자바 script
JavaScript 의 Object. defineProperty () 함수 이해 하기
오늘 의 내용 에 들 어가 기 전에 우 리 는 먼저 이런 장면 을 고려 할 수 있다. 너의 프로젝트 에서 너 는 다음 과 같은 대상 이 있다.
var dreamapple = {
    firstName: 'dream',
    lastName: 'apple'
};

우리 의 요 구 는 dreamapple 에 하나의 fullName 속성 을 추가 하 는 것 이다. dreamapplefirstName 또는 lastName 에 변화 가 생 겼 을 때 fullName 도 이에 따라 변화 해 야 한다.그리고 우리 가 fullName 의 값 을 설 정 했 을 때 그 에 상응하는 firstNamelastName 도 이에 따라 변화 가 발생 한다.그럼 우 리 는 어떻게 해 야 하나 요?
만약 당신 이 Vue.js 를 사용 한 적 이 있다 면, 당신 은 그것 의 을 사용 하여 이 목적 을 달성 할 수 있 습 니 다. 아마도 코드 는 아래 와 같 을 것 입 니 다.
// ...
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...

만약 당신 이 Angular 1.x 를 사용 한 적 이 있다 면, 당신 은 $watch 을 사용 하여 이 목적 을 달성 할 수 있 습 니 다. 아마도 코드 는 아래 와 같 을 것 입 니 다.
//         var vm = this;
$scope.$watch('vm.firstName', function() {
    vm.fullName = vm.firstName + ' ' + vm.lastName;
});
$scope.$watch('vm.lastName', function() {
    vm.fullName = vm.firstName + ' ' + vm.lastName;
});
$scope.$watch('vm.fullName', function() {
    var names = vm.fullName.trim().split(' ');
    if(2 === names.length) {
        vm.firstName = names[0];
        vm.lastName = names[1];
    }
    else {
        // TODO
    }
});

그럼 우 리 는 원생 JavaScript 을 사용 하면 이 목적 을 달성 할 수 있 습 니까?그럼요.그럼 저희 가 어떻게 해 야 되 죠?비교적 간단 한 방법 은 이 대상 의 속성 fullName 에 하나 getter 와 하나 setter 를 설정 하 는 것 이다. 이것 은 ES5 의 특성 이기 때문에 비교적 낮은 버 전의 브 라 우 저 는 이러한 특성 을 지원 하지 않 지만 기본 적 인 모든 현대 브 라 우 저 는 이미 지원 한다. 우 리 는 아래 의 코드 만 쓰 면 된다.
var dreamapple = {
    firstName: 'dream',
    lastName: 'apple',
    get fullName() {
        return this.firstName + ' ' + this.lastName;
    },
    set fullName(fullName) {
        var names = fullName.trim().split(' ');
        if(2 === names.length) {
            this.firstName = names[0];
            this.lastName = names[1];
        }
    }
};

dreamapple.firstName = 'Dream';
dreamapple.lastName = 'Apple';
console.log(dreamapple.fullName); // Dream Apple

dreamapple.fullName = 'Jams King';
console.log(dreamapple.firstName); // Jams
console.log(dreamapple.lastName); // King

너무 편 하 죠?우 리 는 dreamapple 이 대상 에 게 속성 fullNamegettersetter 방법 을 설정 함으로써 우리 가 원 하 는 그런 효 과 를 얻 었 다.
물론 더 좋 은 방법 은 Object.defineProperty() 이라는 함 수 를 사용 하 는 것 입 니 다. 다음은 이 함 수 를 잘 연구 하 는 것 입 니 다. 이 방법의 역할 은 한 대상 에 새로운 속성 을 직접 정의 하거나 이미 존재 하 는 속성 을 수정 하고 이 대상 을 되 돌려 주 는 것 입 니 다.우 리 는 먼저 이 방법 을 어떻게 사용 하 는 지 살 펴 보 자.
Object.defineProperty(obj, prop, descriptor)

그 중에서 매개 변수 obj 는 속성 을 정의 해 야 하 는 대상 을 나타 낸다. 매개 변수 prop 는 정의 되 거나 수정 되 어야 하 는 속성 명 을 나타 낸다. 매개 변수 descriptor 는 바로 우리 가 정의 하 는 그 속성 prop 의 설명 이다.우 리 는 다음 에 주로 이것 descriptor 을 설명 한다. 그것 은 하나의 대상 이 고 많은 속성 이 있다. 우 리 는 다음 에 이런 속성 들 이 무엇 에 쓰 이 는 지 분석 할 것 이다.
  • value 이 속성 에 대응 하 는 값 은 유효한 자 바스 크 립 트 값 (수치, 대상, 함수 등) 일 수 있 습 니 다. 기본 값 은 undefined 입 니 다. 우 리 는 아래 의 작은 예 를 볼 수 있 습 니 다.
    var dream = {};
    Object.defineProperty(dream, 'name', {
        value: 'dreamapple'
    });
    
    console.log(dream.name); // dreamapple
    dream.name = 'apple'; //   name  
    console.log(dream.name); //    apple,   dreamapple
    위의 코드 에서 볼 수 있 습 니 다. 우 리 는 dream 에 새로운 속성 name 을 정 의 했 습 니 다. 그리고 우 리 는 이 속성 을 인쇄 하 는 것 이 우리 가 예 상 했 던 것 처럼 얻 었 습 니 다.dreamapple; 그러나 우리 가 이 속성 을 바 꾸 려 고 시 도 했 을 때 이 속성 은 변 하지 않 았 고 처음으로 우리 가 부여 한 값 이 었 다. 이것 은 왜 일 까? 원래 우리 의 이 속성 writabletrue 로 수식 되 었 을 때 만 우리 의 이 속성 은 수정 할 수 있 었 다.
  • writable 은 이 속성의 writabletrue 일 때 만 이 속성 이 할당 연산 자 에 의 해 바 뀔 수 있 습 니 다. 기본 값 은 false 입 니 다. 우 리 는 위의 코드 를 수정 하여 속성 name 을 수정 할 수 있 습 니 다.
    Object.defineProperty(dream, 'name', {
        value: 'dreamapple',
        writable: true
    });
    
    console.log(dream.name); // dreamapple
    dream.name = 'apple'; //   name  
    console.log(dream.name); // apple
    우 리 는 writabletrue 으로 수정 할 때 name 속성 을 수정 할 수 있 습 니 다.
  • enumerable 이라는 특성 은 우리 가 정의 하 는 속성 이 매 거 진 유형 인지 여 부 를 결정 합 니 다. 기본 값 은 false 입 니 다. 우리 가 그것 을 true 으로 설정 할 때 만 이 속성 을 사용 할 수 있 습 니 다 for(prop in obj)Object.keys() 에서 매 거 진 것 입 니 다. 아래 와 같이
    Object.defineProperty(dream, 'a', {
        value: 1,
        enumerable: false //     
    });
    Object.defineProperty(dream, 'b', {
        value: 2,
        enumerable: true //    
    });
    
    //      b
    for(prop in dream) {
        console.log(prop);
    }
    
    console.log(Object.keys(dream)); // ['b']
    
    console.log(dream.propertyIsEnumerable('a')); // false
    console.log(dream.propertyIsEnumerable('b')); // true
    따라서 우리 가 대상 에 게 매 거 진 속성 을 추가 하려 면 다음 과 같이 해 야 합 니 다.enumerablefalse 로 설정 합 니 다.
  • configurable 이라는 특성 은 대상 의 속성 이 삭 제 될 수 있 는 지, 그리고 writable 특성 을 제외 한 다른 특성 이 수 정 될 수 있 는 지 를 결정 합 니 다. 또한 writable 특성 값 은 false 코드 예 시 를 써 서 이 기능 을 보 여 드릴 수 있 습 니 다.
    Object.defineProperty(dream, 'c', {
        value: 3,
        configurable: false
    });
     //throws a TypeError
    Object.defineProperty(dream, 'c', {
        configurable: true
    });
     //throws a TypeError
    Object.defineProperty(dream, 'c', {
        writable: true
    });
     //won't throws a TypeError
    Object.defineProperty(dream, 'c', {
        writable: false
    });
    delete dream.c; //         
    console.log(dream.c); // 3 
  • get 은 속성 에 getter 을 제공 하 는 방법 입 니 다. getter 이 없 으 면 undefined 입 니 다. 이 방법 은 속성 값 으로 되 돌아 갑 니 다. 기본 값 은 undefined 입 니 다.
  • set 는 속성 에 setter 을 제공 하 는 방법 입 니 다. setter 이 없 으 면 undefined 입 니 다. 이 방법 은 유일한 매개 변 수 를 받 아들 이 고 이 매개 변수의 새로운 값 을 이 속성 에 배분 합 니 다. 기본 값 은 undefined 입 니 다. 이 를 알 게 된 후에 우 리 는 더욱 표준적 인 방식 으로 우리 가 글 에서 시작 하 는 문 제 를 해결 할 수 있 습 니 다.
    Object.defineProperty(dreamapple, 'fullName', {
        enumerable: true,
        get: function () {
            return this.firstName + ' ' + this.lastName;
        },
        set: function (fullName) {
            var names = fullName.trim().split(' ');
            if (2 === names.length) {
                this.firstName = names[0];
                this.lastName = names[1];
            }
        }
    });
    그리고 주의해 야 할 것 은.valueget,set 는 공존 할 수 없다. 즉, value 를 정의 한 후에 더 이상 get,set 특성 을 정의 할 수 없다 는 것 이다.
  • 자, 오늘 의 글 은 여기까지 썼 습 니 다. 여러분 들 이 Object.defineProperty(obj, prop, descriptor) 이 방법 에 대해 파악 해 야 한다 고 믿 습 니 다. 그리고 언급 해 야 할 것 은 사실 Vue.js 도 이 함 수 를 바탕 으로 개선 되 었 습 니 다. 상세 한 내용 은 여기 속성의 비밀 을 계산 하 다 를 볼 수 있 습 니 다.
    만약 당신 이 이 글 에 대해 어떤 의견 이나 건 의 를 가지 고 있다 면 여기에서 제기 할 수 있 습 니 다 issues

    좋은 웹페이지 즐겨찾기