JavaScript

8-2. JavaScript 프로퍼티 어트리뷰트(property attributes)

홍주누 2023. 4. 7. 16:39

I. 프로퍼티 어트리뷰트(property attributes)

객체의 프로퍼티가 생성될 때 엔진에 의해 자동 정의되는 상태

 

✨프로퍼티에는 두 종류가 있음

const person = {

  // ⭐️ 1. 데이터 프로퍼티들
  fullName: '홍길동',
  ageInNumber: 25,

  // ⭐️ 2. 접근자 프로퍼티들
  get name () {
    return this.fullName
    .split('')
    .map((letter, idx) => idx === 0 ? letter : '*')
    .join('');
  },
  get age () { return this.ageInNumber + '세'; },
  set age (age) {
    this.ageInNumber = Number(age);
  }
}

console.log(
  person.name, person.age	// 홍** 25세
);

1. 데이터 프로퍼티의 어트리뷰트

 

2. 접근자 프로퍼티의 어트리뷰트

 

 

 

II. object의 프로퍼티 어트리뷰트 관련 정적 메서드

 

1. getOwnPropertyDescriptor, getOwnPropertyDescriptors

 - 객체 프로퍼티 어트리뷰트들의 설명자 (descriptor)를 반환

const person = {

  // ⭐️ 1. 데이터 프로퍼티들
  fullName: '홍길동',
  ageInNumber: 25,

  // ⭐️ 2. 접근자 프로퍼티들
  get name () {
    return this.fullName
    .split('')
    .map((letter, idx) => idx === 0 ? letter : '*')
    .join('');
  },
  get age () { return this.ageInNumber + '세'; },
  set age (age) {
    this.ageInNumber = Number(age);
  }
}

// 특정 프로퍼티를 지정하여 반환
console.log('1.',
  Object.getOwnPropertyDescriptor(person, 'fullName')
);	// {value: '홍길동', writable: true, enumerable: true, configurable: true}
console.log('2.',
  Object.getOwnPropertyDescriptor(person, 'ageInNumber')
);	// {value: 25, writable: true, enumerable: true, configurable: true}
console.log('3.', // set: undefined
  Object.getOwnPropertyDescriptor(person, 'name')
);	// {set: undefined, enumerable: true, configurable: true, get: ƒ}
console.log('4.', // get, set 모두 있음
  Object.getOwnPropertyDescriptor(person, 'age')
);	// {enumerable: true, configurable: true, get: ƒ, set: ƒ}


// 모든 프로퍼티의 어트리뷰트 객체로 묶어 반환
console.log(
  Object.getOwnPropertyDescriptors(person)	// {fullName: {…}, ageInNumber: {…}, name: {…}, age: {…}}
);

반드시 콘솔 창에서 풀어서 확인해볼 것! 

 

 

2. defineProperty, defineProperties

 - 객체의 프로퍼티를 정의

const person = {};

// 한 프로퍼티씩 각각 설정
Object.defineProperty(person, 'fullName', {
  value: '홍길동',
  writable: true
  // 💡 누락한 어트리뷰트는 기본값으로 자동생성
});

Object.defineProperty(person, 'name', {
  get () {
    return this.fullName
    .split('')
    .map((letter, idx) => idx === 0 ? letter : '*')
    .join('');
  }
});

console.log(person, person.name);
console.log( // ⚠️ 누락된 어트리뷰트들 확인해볼 것
  Object.getOwnPropertyDescriptors(person)
);

 

 

 

III. 깊은 동결 (deep freeze)

 - 재귀적으로 객체를 가장 깊숙히까지 동결

 - 주어진 인자 자체를 변형하지 않도록 

function getDeepFrozen(obj) {
  console.log(obj);

  const result = {};
  const propNames = Object.getOwnPropertyNames(obj);

  for (const name of propNames) {
    const value = obj[name];

    result[name] = 
      (value && typeof value === 'object') ?
      getDeepFrozen(value) : value;
  }
  return Object.freeze(result);
}
let myObj = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 3,
      f: {
        g: 4
      }
    }
  }
}

// 여러 번 실행해 볼 것
myObj.a++;
myObj.b.c++;
myObj.b.d.e++;
myObj.b.d.f.g++;

console.log(myObj);
myObj = getDeepFrozen(myObj);

// 여러 번 실행해 볼 것
myObj.a++;
myObj.b.c++;
myObj.b.d.e++;
myObj.b.d.f.g++;

console.log(myObj);