JavaScript 의 Object. defineProperty () 함수 이해 하기
7977 단어 자바 script
오늘 의 내용 에 들 어가 기 전에 우 리 는 먼저 이런 장면 을 고려 할 수 있다. 너의 프로젝트 에서 너 는 다음 과 같은 대상 이 있다.
var dreamapple = {
firstName: 'dream',
lastName: 'apple'
};
우리 의 요 구 는
dreamapple
에 하나의 fullName
속성 을 추가 하 는 것 이다. dreamapple
의 firstName
또는 lastName
에 변화 가 생 겼 을 때 fullName
도 이에 따라 변화 해 야 한다.그리고 우리 가 fullName
의 값 을 설 정 했 을 때 그 에 상응하는 firstName
와 lastName
도 이에 따라 변화 가 발생 한다.그럼 우 리 는 어떻게 해 야 하나 요?만약 당신 이
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
이 대상 에 게 속성 fullName
의 getter
과 setter
방법 을 설정 함으로써 우리 가 원 하 는 그런 효 과 를 얻 었 다.물론 더 좋 은 방법 은 Object.defineProperty() 이라는 함 수 를 사용 하 는 것 입 니 다. 다음은 이 함 수 를 잘 연구 하 는 것 입 니 다. 이 방법의 역할 은 한 대상 에 새로운 속성 을 직접 정의 하거나 이미 존재 하 는 속성 을 수정 하고 이 대상 을 되 돌려 주 는 것 입 니 다.우 리 는 먼저 이 방법 을 어떻게 사용 하 는 지 살 펴 보 자.
Object.defineProperty(obj, prop, descriptor)
그 중에서 매개 변수
obj
는 속성 을 정의 해 야 하 는 대상 을 나타 낸다. 매개 변수 prop
는 정의 되 거나 수정 되 어야 하 는 속성 명 을 나타 낸다. 매개 변수 descriptor
는 바로 우리 가 정의 하 는 그 속성 prop
의 설명 이다.우 리 는 다음 에 주로 이것 descriptor
을 설명 한다. 그것 은 하나의 대상 이 고 많은 속성 이 있다. 우 리 는 다음 에 이런 속성 들 이 무엇 에 쓰 이 는 지 분석 할 것 이다.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
; 그러나 우리 가 이 속성 을 바 꾸 려 고 시 도 했 을 때 이 속성 은 변 하지 않 았 고 처음으로 우리 가 부여 한 값 이 었 다. 이것 은 왜 일 까? 원래 우리 의 이 속성 writable
이 true
로 수식 되 었 을 때 만 우리 의 이 속성 은 수정 할 수 있 었 다. writable
가 true
일 때 만 이 속성 이 할당 연산 자 에 의 해 바 뀔 수 있 습 니 다. 기본 값 은 false 입 니 다. 우 리 는 위의 코드 를 수정 하여 속성 name
을 수정 할 수 있 습 니 다. Object.defineProperty(dream, 'name', {
value: 'dreamapple',
writable: true
});
console.log(dream.name); // dreamapple
dream.name = 'apple'; // name
console.log(dream.name); // apple
우 리 는 writable
을 true
으로 수정 할 때 name
속성 을 수정 할 수 있 습 니 다. 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
따라서 우리 가 대상 에 게 매 거 진 속성 을 추가 하려 면 다음 과 같이 해 야 합 니 다.enumerable
을 false
로 설정 합 니 다. 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
getter
을 제공 하 는 방법 입 니 다. getter
이 없 으 면 undefined
입 니 다. 이 방법 은 속성 값 으로 되 돌아 갑 니 다. 기본 값 은 undefined 입 니 다. 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];
}
}
});
그리고 주의해 야 할 것 은.value
와 get,set
는 공존 할 수 없다. 즉, value
를 정의 한 후에 더 이상 get,set
특성 을 정의 할 수 없다 는 것 이다. Object.defineProperty(obj, prop, descriptor)
이 방법 에 대해 파악 해 야 한다 고 믿 습 니 다. 그리고 언급 해 야 할 것 은 사실 Vue.js
의
도 이 함 수 를 바탕 으로 개선 되 었 습 니 다. 상세 한 내용 은 여기 속성의 비밀 을 계산 하 다 를 볼 수 있 습 니 다.만약 당신 이 이 글 에 대해 어떤 의견 이나 건 의 를 가지 고 있다 면 여기에서 제기 할 수 있 습 니 다 issues
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.