일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 타입스크립트
- react-native-vision-camera
- Flipper
- craco
- react-native
- 제네릭타입
- Typescript
- React
- 코드숨
- 프로그래머스
- 자료구조와알고리즘
- 리액트네이티브
- 파스에러
- 배열
- 크라코
- Android
- reactnative
- ios
- javascript
- 모던자바스크립트
- 리액트
- 자바스크립트
- 유니온타입
- react-native-camera-roll
- slice
- js
- 리액트쿼리
- react-native-image-picker
- sort( )
- react-hook-form
- Today
- Total
KassyLog
[모던 자바스크립트]프로퍼티 어트리뷰트 본문
내부슬롯과 내부 메서드
자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에 사용하는 의사 프로퍼티와 의사 메서드다.
자바스크립트 엔진의 내부 로직이므로 원칙적으로 자바스크립트는 내부슬롯과 내부메서드에 직접적으로 접근하거나 호출할 수 있는 방법을 제공하지 않는다. 단, 일부 내부슬롯과 내부메서드에 한하여 간접적으로 접근할 수 있는 수단을 제공하기는 한다.
프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.
프로퍼티의 상태란 프로퍼티의 값, 값의 갱신 가능 여부, 열거 가능 여부, 재정의 가능 여부를 말한다.
const person = {
name: "Lee"
}
person.age = 20;
//모든 프로퍼티의 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체들을 반환한다.
console.log(Object.getOwnPropertyDescriptor(person));
/*
{
name: { value: "Lee", writable: true, enumerable: true, configurable: true },
age: { value: 20, writable: true, enumerable: true, configurable: true }
}
*/
데이터 프로퍼티와 접근자 프로퍼티
데이터 프로퍼티 : 키와 값으로 구성된 일반적인 프로퍼티.
[[Value]] : value - 접근시 반환되는 값
[[Writable]] : writable - 값의 변경 여부를 나타내며 true or false
[[Enumerable]] : enumerable - 열거 기능 여부를 나타내며 true or false // false시 for ... in, Object.keys 메서드 등으로 열거 불가
[[Configurable]]: configurable - 재정의 가능 여부를 나타내며 true or false // false시 삭제, 변경은 불가하지만,[[Writable]]이 true인 경우 [[Value]]의 변경과 [[Writable]]을 false로 변경하는 것은 허용된다
접근자 프로퍼티 : 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티.
[[Get]] : get - 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수이며, getter 함수가 호출되고 그 결과가 프로퍼티 값으로 반환된다.
[[Set]] : set - 접근자 프로퍼티를 통해 프로퍼티의 값을 저장할 때 호출되는 함수이며, setter 함수가 호출되고 그 결과가 프로퍼티 값으로 저장된다.
[[Enumerable]] : enumerable - 데이터 프로퍼티와 같다.
[[Configurable]] : configurable - 데이터 프로퍼티와 같다.
프로퍼티의 정의
새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것을 말한다. 예를들어, 프로퍼티 값을 갱신 가능하도록 할 것인지, 프로퍼티를 열거 가능하도록 할 것인지, 프로퍼티를 재정의 가능하도록 할 것인지 정의할 수 있다. 이를 통해 객체의 프로퍼티가 어떻게 동작해야 하는지를 명확히 정의할 수 있다.
const person = {};
Object.defineProperty(person, 'firstName', {
value: 'Ungmo',
writable: true,
enumerable: true,
configurable: true,
});
Object.defineProperty(person, 'lastName', {
value: 'Lee'
});
let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log('firstName', descriptor);
// firstName { value: "Ungmo", writable: true, enumerable: true, configurable: true }
descriptor = Object.getOwnPropertyDescriptor(person, 'lastName');
console.log(descriptor);
// lastName { value: "Lee", writable: false, enumerable: false, configurable: false }
console.log(Object.keys(person)); // ["firstName"]
person.lastName = 'Kim';
delete person.lastName;
descriptor = Object.getOwnPropertyDescriptor(person, 'lastName')
console.log('lastName', descriptor);
// lastName { value: "Lee", writable: false, enumerable: false, configurable: false }
Object.defineProperty(person, 'fullName', {
get() {
return this.firstName + ' ' + this.lastName;
},
set(name) {
this.firstName = name.split(' ')[0];
this.lastName = name.split(' ')[1];
},
enumerable: true,
configurable: true
});
descriptor = Object.getOwnPropertyDescriptor(person, 'fullName');
console.log('fullName', descriptor);
// fullName { get: f, set: f, enumerable: true, configurable: true }
person.fullName = 'Heegun Lee';
console.log(person); // { firstName: "Heegun", lastName: "Lee" }
Object.defineProperty 메서드로 프로퍼티를 정의할 때 일부 생략 할 수 있다. 생략했을 때의 기본값은 아래와 같다.
value - undefined
get - undefined
set - undefined
writable - false
enumerable - false
configurable - false
Object.defineProperty는 하나의 프로퍼티만 정의할 수 있다. Object.defineProperties를 사용하면 여러 개의 프로퍼티를 한 번에 정의할 수 있다.
객체 변경 방지
객체는 변경 가능한 값이므로 재할당 없이 직접 변경할 수 있다. 즉, 프로퍼티를 추가하거나 삭제할 수 있고, 프로퍼티 값을 갱신할 수 있으며, Object.defineProperty Ehsms Object.defineProperties 메서드를 사용하여 프로퍼티 어트리뷰트를 재정의할 수도 있다.
Object.preventExtensions (객체 확장 금지)
객체의 확장을 금지한다. 확장이 금지된 객체는 프로퍼티 추가가 금지된다.
const person = [ name: 'Lee', isMale: true };
const isExtensible1 = Object.isExtensible(person) // true
Object.preventExtensions(person);
const isExtensible2 = Object.isExtensible(person) // false
person.age = 20 // 무시. strict 모드에서는 에러
console.log(person); // { name: "Lee", isMale: true }
delete person.name;
console.log(person); // { isMale: true }
Object.defineProperty(person, 'age', { value: 20 });
// TypeError: Cannot define property age, object is not extensible
Object.seal(객체 밀봉)
const person = { name: 'Lee', isMale: true };
const isSealed1 = Object.isSealed(person) // false
Object.seal(person);
const isSealed2 = Object.isSealed(person); // true
console.log(Object.getOwnPropertyDescriptors(person)); // configurable이 false다.
/*
{
name: { value: "Lee", writable: true, enumerable: true, configurable: false }
isMale: { value: true, writable: true, enumerable: true, configurable: false }
}
*/
person.age = 20; // 무시. strict 모드에서는 에러
console.log(person); // { name: "Lee", isMale: true }
delete person.name // 무시. strict 모드에서는 에러
console.log(person); // { name: "Lee", isMale: true }
person.name = 'Kim'; // 값 갱신은 가능하다.
console.log(person); // { name: "Kim", isMale: true }
Object.defineProperty(person, 'name', { configurable: true });
// TypeError: Cannot redefine property: name
Object.freeze(객체 동결)
const person = { name: 'Lee' };
const isFrozen1 = Object.isFrozen(person); // false
Object.freeze(person);
const isFrozen2 = Object.isFrozen(person); // true
console.log(Object.getOwnPropertyDescriptors(person)); // writable, configurable이 false다
/*
{
name: { value: "Lee", writable: false, enumerable: true, configurable: false },
isMale: { value: true, writable: false, enumerable: true, configurable: false }
}
*/
person.age = 20; // 무시. strict 모드에서는 에러
console.log(person); // { name: "Lee", isMale: true }
delete person.name; // 무시. strict 모드에서는 에러
console.log(person); // { name: "Lee", isMale: true }
person.name = 'Kim'; // 무시. strict 모드에서는 에러
console.log(person); // { name: "Lee", isMale: true }
Object.defineProperty(person, 'name', { configurable: true });
// TypeError: Cannot redefine property: name
deep freeze(불변객체)
const person = {
name: 'Lee',
isMale: true,
address: {
city: 'Seoul'
}
}
function deepFreeze(target) {
if (target && typeof target === 'object' && !Object.isFrozen(target)) {
Object.freeze(target);
const keys = Object.keys(target); // ['name', 'isMale', 'address']
const keyLength = key.length; // 3
for (let i = 0; i < keyLength; i++) {
deepFreeze(target[key]));
}
}
return target;
}
deepFreeze(person);
const isFrozenPerson = Object.isFrozen(person); // true
const isFrozenAddress = Object.isFrozen(person.address); // true
person.address.city = 'Busan';
console.log(person); // { name: "Lee", isMale: true, address: { city: "Seoul" }}
'javascript' 카테고리의 다른 글
Date( ) 생성자로 달력만들기 (2) | 2023.01.10 |
---|---|
[모던 자바스크립트]생성자 함수에 의한 객체 생성 (0) | 2023.01.08 |
[모던 자바스크립트]스코프 (0) | 2023.01.01 |
[모던 자바스크립트]실행 컨텍스트 (0) | 2023.01.01 |
[모던 자바스크립트]함수 (0) | 2022.12.25 |