Object.defineProperty()
객체에 새로운 속성을 직접 정의하거나 이미 존재하는 속성을 수정한 후, 해당 객체를 반환합니다.
Object.defineProperty(obj, prop, descriptor);
- obj : 속성을 정의할 객체
- prop: 새로 만들거나 수정하려는 속성 이름
- descriptor : 객체에 정의하는 속성을 기술하는 객체
desciptor 의 속성 목록
속성 | 설명 | 기본 값 |
value | 속성값 | undefined |
configurable | true-> 속성값을 변경하거나 삭제 가능 | false |
writable | true-> 할당 연산자로 속성의 값 변경 가능 | false |
enumarable | true-> 열거가 가능. for in 과 같은 반복문에서 해당 프로퍼티 반환 | false |
set | 속성 설정자 함수 | undefined |
get | 속성 접근자 함수. 속성 접근시 해당 함수의 반환값이 속성의 값 | undefined |
desciptor의 속성 value과 writable그리고 configurable에 대한 예제.
const object1 = { property1: 11 };
Object.defineProperty(object1, "property2", {
value: 22,
writable: false, //할당연산자로 속성값 변경 불가
configurable: false, // 속성 변경 or 삭제 불가
//q. writable의 속성값 변경이랑 configurable 속성 변경이랑 차이가 뭐지?
});
object1.property2 = 22; //수정이 되지 않지 않지만 에러가 나지 않습니다.
//strict mode일경우 에러를 반환합니다.
delete object1.property2; //삭제가 되지 않지만 에러가 나지 않는다.
console.log(object1); //property2가 보이지 않는다 왜일까?
console.log(object1.property2); //22
desciptor의 속성 enumarable에 대한 예제.
const yuJin = {
name: "안유진",
year: 2003,
get age() {
//getter, yuJin.age을 사용해 프로퍼티를 읽으려고 할 때 실행
return new Date().getFullYear() - this.year;
},
set age(age) {
// setter, yuJin.age = value로 프로퍼티에 값을 할당하려 할 때 실행
this.year = new Date().getFullYear() - age;
},
};
yuJin.birthday = "0521"; //닷노테이션으로 정의된 프로퍼티의 Attribute의 속성값은
//writable,enumerable,configurable 가 전부 true 로 설정되어 변경 삭제가 가능하다.
Object.defineProperty(yuJin, "height", {
value: 172,
// writable: false, 작성을 안하면 닷노테이션과 다르게 default는 false로 정의된다.
enumerable: true,
// configurable: false,
});
console.log(Object.keys(yuJin)); //열거가 가능하다
//[ 'name', 'year', 'age', 'birthday', 'height' ]
for (let key in yuJin) {
console.log(key);
}
//name
//year
//age
//birthday
//height
Q. configurable와 writable 모두 속성값을 변경하는 일을 하네요?
configurable와 writable의 기능은 정확히 다음과 같이 정의할 수 있습니다. (다음과 같은 개념을 이해하기 위해선 property Attribute에 대한 이해가 필요합니다.) writable은 우리가 알고 있듯이 할당연산자= 로 속성값을 변경하는 일을 합니다. 하지만 configurable 은 속성 Attribute의 재정의가 가능한지 여부를 판단하는 일 맡는 다는 것에 차이가 있습니다. Attribute 값 중 속성값을 변경하는 value 가 있어 configurable 개념이 writable 보다 깊은 개념이지만 configurable:false 이고 writable : true 일때는 값 변경과 writable 변경이 가능한 걸 보아 우선순위는 writable로 높다는 느낌이 드네요.
writable
값을 수정 할 수 있는지 여부, false로 설정하면 프로퍼티 값을 수정 할 수 없다. 할당연산자 뿐아니라 defineProperty메서드를 통한 속성값 변경도 가능해보입니다.
yuJin.birthday = "0521";
yuJin[birthday] = "1104";
Object.defineProperty(yuJin, "hair", {
value: "long",
//configurable: true,
writable: true,
});
console.log(Object.getOwnPropertyDescriptor(yuJin, "hair"));
// {
// value: 'long',
// writable: true,
// enumerable: false,
// configurable: false
// }
Object.defineProperty(yuJin, "hair", {
value: "short",
});
console.log(yuJin.hair); //short
configurable
프로퍼티 어트리뷰트의 재정의가 가능한지 여부를 판단합니다. false 일경우 프로퍼티 삭제나 어트리뷰트 변경이 금지됩니다. *단 writable이 true인 경우 값 변경과 writable을 변경하는 건 가능하다.
Object.defineProperty(yuJin, "hair", {
value: "long",
configurable: false,
});
console.log(Object.getOwnPropertyDescriptor(yuJin, "hair"));
// {
// value: 'long',
// writable: false,
// enumerable: false,
// configurable: false
// }
Object.defineProperty(yuJin, "hair", {
enumerable: true, //에러
});
Object.defineProperty(yuJin, "hair", {
value: "long",
configurable: true,
});
console.log(Object.getOwnPropertyDescriptor(yuJin, "hair"));
// {
// value: 'long',
// writable: false,
// enumerable: false,
// configurable: false
// }
Object.defineProperty(yuJin, "hair", {
value: "short",
});
console.log(yuJin.hair); //short
참고
! 실습시 메서드 이름을 잘 작성하세요.
Property description must be an object:p
Object.defineProperties() 와 Object.defineProperty() 메서드 둘 다 존재합니다. 객체의 속성을 정의하거나 수정하고 싶을 때 다수의 속성일때는 Object.defineProperties() 메서드, 속성하나일때는 Object.defineProperty() 메서드를 쓰니 주의가 필요합니다.
Object.defineProperty() 실습 중간 Object.defineProperties()가 존재하는 지 모르고 자동완성으로 빠르게 작성했습니다. 그래서 예상과 다르게 node는 defineProperties로 인식해 두번째 인자가 객체여야 한다고 주장하고 있는 모습입니다. (허헣)
더 질문하기
Q. property2가 보이지 않는다. 왜일까?
첫 번째 예제를 잘 보신 분들은 해당 주석을 본적이 있을 겁니다. Object.definePropty() 공부하기 초반 definePropty메서드를 사용해 descriptor 중 writable과 configurable 예제를 실습하고 있었습니다. writable와 configurable를 false 로 설정한 object1의 프로퍼티 "propety2"는 object1을 출력할 당시 "propety2"만 출력되지 않았습니다. 존재는 하는 데도요.
Object.definePropty() 공부 막마지인 지금은 이 질문의 답을 할 수 있겠네요. Object.definePropty()를 정의할 당시 descriptor를 정의하지 않는 다면, writable, configurable, enumerable 모두 false 처리 됩니다. 따라서 해당 예제는 enumerable 의 값이 false 로 처리되어 열거불가능한 프로퍼티로 정의되었습니다. 따라서 object1를 열거하는 console.log(object1);에서는 propety2만 보이지 않게 된 것이죠
const object1 = { property1: 11 };
Object.defineProperty(object1, "property2", {
value: 22,
writable: false, //할당연산자로 속성값 변경 불가
configurable: false, // 속성 변경 or 삭제 불가
//q. writable의 속성값 변경이랑 configurable 속성 변경이랑 차이가 뭐지?
});
object1.property2 = 22; //수정이 되지 않지 않지만 에러가 나지 않습니다.
//strict mode일경우 에러를 반환합니다.
delete object1.property2; //삭제가 되지 않지만 에러가 나지 않는다.
console.log(object1); //property2가 보이지 않는다 왜일까?
console.log(object1.property2); //22
더 공부하기
Property Attribute
object property
객체의 프로퍼티는 크게 두가지로 나눌 수 있습니다. 우리가 흔히 key & value 형태의 프로퍼티들이 data propety에 해당됩니다. 새롭게 알게 된점은 접근자 프로퍼티입니다. 새로운 종류의 프로퍼티이며 본질은 함수인데, 외부 코드에서는 함수가 아닌 일반적인 프로퍼티처럼 보이는 특이한 점입니다. 접근자 프로퍼티에는 getter(조회) 와 setter(설정)로 표현됩니다. 객체 리터럴 안에서 getter는 get 으로 setter는 set으로 표현됩니다.
- 데이터 프로퍼티(data propety) : 키와 값으로 형성된 실질적 값을 가지고 있는 프로퍼티
- 접근자 프로퍼티 (accessor propety) : 다른 값을 가져오거나 설정할 때 호출되는 함수로 구성된 프로퍼티입니다. 자체적인 값이 없다는 것이 특징입니다.
const yuJin = {
name: "안유진",
year: 2003,
get age() {
//getter, yuJin.age을 사용해 프로퍼티를 읽으려고 할 때 실행
return new Date().getFullYear() - this.year;
},
set age(age) {
// setter, yuJin.age = value로 프로퍼티에 값을 할당하려 할 때 실행
this.year = new Date().getFullYear() - age;
},
};
console.log(yuJin);
console.log(yuJin.age); //getter 가 실행된다.
yuJin.age = 32; //setter 가 실행된다.
console.log(yuJin.age); //32
console.log(yuJin.year); //1991
property Attribute
각각의 프로퍼티는 Attribute을 가지고 있습니다. property Attribute는 해당 프로퍼티의 값에 대한 정보 또는 속성값의 변경가능 여부 등 해당 프로퍼티의 정보를 정의하는 속성입니다.프로퍼티의 종류마다 다른 Attribute를 가지고 있습니다.
console.log(Object.getOwnPropertyDescriptor(yuJin, "name"));
console.log(Object.getOwnPropertyDescriptor(yuJin, "age"));
//데이터 프로퍼티
/*
*{ value: '안유진', writable: true, enumerable: true, configurable: true }
*/
//접근자 프로퍼티
/*
*{
* get: [Function: get age],
* set: [Function: set age],
* enumerable: true,
* configurable: true
*}
*/
출처
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object.defineProperty() - JavaScript | MDN
Object.defineProperty() 정적 메서드는 객체에 새로운 속성을 직접 정의하거나 이미 존재하는 속성을 수정한 후, 해당 객체를 반환합니다.
developer.mozilla.org
https://ko.javascript.info/property-accessors
프로퍼티 getter와 setter
ko.javascript.info
https://www.youtube.com/watch?v=ZOVG7_41kJE
'JavaScript' 카테고리의 다른 글
Property Attribute (0) | 2023.10.26 |
---|---|
[Javascript] 프로그래머스 - 문자열 다루기 기본 (1) | 2023.10.07 |
MSW.js으로 Mocking with TS (1) | 2023.10.03 |
var, let, const (0) | 2023.09.06 |
JavaScript에서 비동기 (0) | 2023.09.05 |