Multi Developer SuHo

자바스크립트 프로퍼티 어트리뷰트(Property Attribute) 본문

JavaScript

자바스크립트 프로퍼티 어트리뷰트(Property Attribute)

Dreaming Developer Student 2023. 11. 20. 16:06
SMALL

 글을 쓰기 앞서 모든  내용과 소스들은 다음과 같은 강의 플랫폼에서 응용하여  작성하였습니다.
출처: https://inf.run/xNcEg

 

[무료] [코드팩토리] [입문] 9시간만에 끝내는 코드팩토리의 Javascript 무료 풀코스 - 인프런 | 강의

이 강의 하나만으로 인기 Javascript 프레임워크들과 Typescript를 배울 수 있는 기본을 다질 수 있습니다., 자바스크립트 문법 마스터,9시간 만에 무료로 할 수 있어요! ✨ 자바스크립트 문법,한 강의

www.inflearn.com

안녕하세요~ 요즘  활동이 빈번해서요ㅜㅜ 학교 시험도 있고 병행해서 글이 많이 올라오지 않습니다. 양해바랍니다~~ 
이번에는 자바스크립트에서 프로퍼티 어트리뷰트(Property Attribute)에 대해 알아보겠습니다. 일단 프로퍼티(Property)어트리뷰트(Attribute)를 구분해보겠습니다. 
자바스크립트에서 프로퍼티(Property)는 이름(또는 키)과 값으로 이루어져  있고,  프로퍼티는 객체의 특정 특징이나 속성을 나타냅니다.
 어트리뷰트(Attribute)는 객체의 프로퍼티(Property)에 대한 특성을 나타냅니다. 

 



프로퍼티의 종류와  프로퍼티 어트리뷰트를 구분한 주석구문입니다.

/**
 * Property Attribute - Property에 또 속성이 추가로 생성이 된다. 자동으로 생성되는 속성들이 있다.
 * 
 * 1) 데이터 프로퍼티 - 키와 값으로 형성된 실질적 값을 갖고있는 프로퍼티
 * 2) 엑세서 프로퍼티 - 자체적으로 값을 갖고 있지 않지만 다른 값을 가져오거나
 *                     설정할때 호출되는 함수로 구성된 프로퍼티 
 *                     예를들면 Getter와 Setter 
 * 데이터 프로퍼티와 엑세서 프로퍼티를 구분하는 방법은 getOwnPropertyDescriptor 를 실행하여
 * 어떤 형태로 프로퍼티 어트리뷰트가 나오는지 확인해보면 알 수 있다.
 * 엑세서 프로퍼티는 벨류라는 프로퍼티 어트리뷰트가 존재하지 않는다.
 * get 과 set 이라는 프로퍼티 어트리뷰트가 존재한다.
 * 
 *  
 * 일반적인 프로퍼티 어트리뷰트
 * 1) value - 실제 프로퍼티의(Property) 값
 * 2) writable - 값을 수정할 수 있는지 여부. false로 설정하면 프로퍼티 값을
 *               수정 할 수 없다.
 * 3) enumerable - 열거가 가능한지 여부. for...in 룹 등을 사용할 수 있으면 
 *                 true를 반환한다.
 * 4) configurable - 프로퍼티 어트리뷰트(Property Attribute)의 재정의가 가능한지 여부를 판단한다.
 *                   false 일 경우 프로퍼티(Property) 삭제나 어트리뷰트(Attribute) 
 *                   변경이 금지된다. 단, writable이 true인 경우 
 *                   값 변경과 writable을 변경하는건 가능하다.
 * 
 *  대문자로 시작하면은 생성자 함수 이거나 클래스의 이름
    생성자 함수 또는 클래스의 . 이 붙으면 Static 함수(클래스에 직접적으로 붙어있는 값) 
    어떤 값들을 넣어야하나? -> 1. Property Attribute 를 알고 싶은 객체 2. 정보를 가져오고 싶은 프로퍼티에 키값 
 */

 

제가 작성한 소스코드에 주석을 달아서 설명하였습니다. 

const winter = {  //변수선언
    name: '윈터',
    year: 2001, 
};


console.log(Object.getOwnPropertyDescriptor(winter,'year'));
console.log('----------------');

console.log(Object.getOwnPropertyDescriptor(winter,'name'));
//getOwnPropertyDescriptors -> Parameter(파라미터)에다가 그냥 객체만 넣을수 있다.
console.log(Object.getOwnPropertyDescriptors(winter));
console.log('----------------');
const winter2 = {
    name: '윈터', // Data Property
    year: 2001,  // Data Property

    get age(){ //Excssor Property    
     return new Date().getFullYear() - this.year; //현재가 몇년도 인지 알수 있는 함수 
    },

    set age(age){ //Excssor Property    
        this.year = new Date().getFullYear() - age; 
        // 입력받은 age를 현재년도에서 빼면 몇년도생인지 알 수 있다.
    }
}

console.log(winter2);
console.log(winter2.age); //2023 - 2001 = 22
console.log('----------------');
winter2.age = 36;
console.log(winter2.age);
console.log(winter2.year);
console.log('----------------');
//Getter와 Setter에 Property Attribute
console.log(Object.getOwnPropertyDescriptor(winter2, 'age'));

// winter2['height'] = 164;  winter2 변수에다 key를 추가하고 싶은 방법
// console.log(winter2);

// 변경하면서 프로퍼티를 추가하고 싶을 때 ->  DefineProperty 함수 사용
Object.defineProperty(winter2, 'height', { // 첫번째 값에는 프로퍼티를 추가하고 싶은 객체, 두 번째 값에는 키값, 
    //세 번째 Property Attribute 를 실제로 정의할 수 있다.
        value: 163,
        writable: true,
        enumerable: true,
        configurable: true,
// 만약에 writable 부터 configurable 까지 값들을 추가를 해주지 않으면 전부 false로 들어간다
})
console.log(winter2);
console.log(Object.getOwnPropertyDescriptor(winter2, 'height'));
console.log('----------------');

winter2.height = 173;
console.log(winter2);

Object.defineProperty(winter2, 'height', { 
    writable:false, // writable만 false로 변경
});
console.log(Object.getOwnPropertyDescriptor(winter2, 'height'));

// height 변수에 들어간 값을 원래 값으로 변경
console.log('----------------');
winter2.height = 162;
console.log(winter2);

/**
 * Enumerable  - 열거를 할 수 있는지 알려주는 기능
 */
console.log(Object.keys(winter2)); // 키값들을 리스트로 받을 수 있다.
for(let key in winter2){
    console.log(key);
} // for 룹을 사용하여 모든 키값들을 루핑 할 수 있다.
console.log('----------------');

Object.defineProperty(winter2, 'name', { 
    enumerable:false, //name 값에 enumerable를 false로 설정
});

console.log(Object.getOwnPropertyDescriptor(winter2, 'name')); // enumerable이 false로 설정된거를 볼 수 있다.

console.log('--------------------')
console.log(Object.keys(winter2));
for(let key in winter2){
    console.log(key); // name 프로퍼티에 Enumerable를 false로 설정했기 때문에 더 이상 열거를 할 수 없다.
}
console.log(winter2); 
console.log(winter2.name); //name이라는 값은 존재하지만 열거를 할 수 없을 뿐이다.
console.log('----------------');
/**
 * Configurable
 */
Object.defineProperty(winter2, 'height', { //winter2에 key를 Configurable를 false로 설정
    writable: true,
    configurable: false,
});
console.log(Object.getOwnPropertyDescriptor(winter2, 'height')); // Configurable이 false로 설정되어 있는 것을 확인
console.log('----------------');
// Object.defineProperty(winter2, 'height', {
//     enumerable: false,
// }); 

Object.defineProperty(winter2, 'height', {
    value: 163, //height 에 value 값을 163으로 변경
});
console.log(Object.getOwnPropertyDescriptor(winter2, 'height'));
console.log('----------------');
Object.defineProperty(winter2, 'height', {
    writable:false, // writable를 false로 변경
});
console.log(Object.getOwnPropertyDescriptor(winter2, 'height'));



// Object.defineProperty(winter2, 'height', {
//     writable:true, // writable를 true로 변경할려면 오류 발생
// }); 
// Configurable를 false로 만들면 일단 기본적으로 프로퍼티 어트리뷰트는 변경이 불가능하다. 
// 예외 - writable이 true 일때는 value값은 변경할 수 있고, writable 이 true -> false 변경 가능, 하지만 false -> true 는 변경 할 수 없다.



 

 

 

다음 소스를 출력하면 다음과 같이 출력됩니다. 

{ value: 2001, writable: true, enumerable: true, configurable: true }
----------------
{ value: '윈터', writable: true, enumerable: true, configurable: true }
{
  name: { value: '윈터', writable: true, enumerable: true, configurable: true },
  year: { value: 2001, writable: true, enumerable: true, configurable: true }
}
----------------
{ name: '윈터', year: 2001, age: [Getter/Setter] }
22
----------------
36
1987
----------------
{
  get: [Function: get age],
  set: [Function: set age],
  enumerable: true,
  configurable: true
}
{ name: '윈터', year: 1987, age: [Getter/Setter], height: 163 }
{ value: 163, writable: true, enumerable: true, configurable: true }
----------------
{ name: '윈터', year: 1987, age: [Getter/Setter], height: 173 }
{ value: 173, writable: false, enumerable: true, configurable: true }
----------------
{ name: '윈터', year: 1987, age: [Getter/Setter], height: 173 }
[ 'name', 'year', 'age', 'height' ]
name
year
age
height
----------------
{ value: '윈터', writable: true, enumerable: false, configurable: true }
--------------------
[ 'year', 'age', 'height' ]
year
age
height
{ year: 1987, age: [Getter/Setter], height: 173 }
윈터
----------------
{ value: 173, writable: true, enumerable: true, configurable: false }
----------------
{ value: 163, writable: true, enumerable: true, configurable: false }
----------------
{ value: 163, writable: false, enumerable: true, configurable: false }
LIST