๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Language/Javascript

[Javascript]์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Property Attribute ์™„๋ฒฝ ์ •๋ฆฌ: ์ดํ•ด์™€ ํ™œ์šฉ ๋ฐฉ๋ฒ•

by YJ Dev 2024. 6. 29.
728x90
๋ฐ˜์‘ํ˜•
SMALL

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Property Attribute์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ๊ธ€์˜ ๋ชฉํ‘œ๋Š” Property Attribute์˜ ๊ฐœ๋…์„ ์ดํ•ดํ•˜๊ณ , ๋‹ค์–‘ํ•œ ํ™œ์šฉ ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๊ผญ ์•Œ์•„์•ผ ํ•  ์ค‘์š”ํ•œ ๊ฐœ๋…์ด๋‹ˆ, ๋๊นŒ์ง€ ์ฝ์–ด์ฃผ์„ธ์š”!

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Property Attribute


์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ Property Attribute๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์ „์— ๊ฐ์ฒด์˜ ๊ธฐ๋ณธ ๊ฐœ๋…์„ ๋จผ์ € ํ™•์ธํ•ด ์ฃผ์„ธ์š”๐Ÿ˜

""

[Javascript]์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด ์™„๋ฒฝ ๊ฐ€์ด๋“œ: ์„ ์–ธ, ์‚ฌ์šฉ๋ฒ•, ๋ณต์‚ฌ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ฐ์ฒด(Object)๋Š” ๋งค์šฐ ์ค‘์š”ํ•œ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์˜ ๊ตฌ์กฐ๋กœ ๋ฌถ์–ด ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๊ฐœ๋…๋ถ€ํ„ฐ ๊ณ ๊ธ‰ ํ™œ

creativevista.tistory.com


01. Property Attribute๋ž€?๐Ÿ“š

Property Attribute๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์˜ ์†์„ฑ์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. ์†์„ฑ์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

  • Data Property Attributes (๋ฐ์ดํ„ฐ ์†์„ฑ)
  • Accessor Property Attributes (์ ‘๊ทผ์ž ์†์„ฑ)

๊ฐ ์†์„ฑ์˜ ์ข…๋ฅ˜์™€ ์—ญํ• ์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


02. Data Property Attributes๐Ÿ’พ

Data Property Attributes๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์†์„ฑ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

1. ๊ฐ’(Value)

  • ์†์„ฑ์˜ ์‹ค์ œ ๊ฐ’์ž…๋‹ˆ๋‹ค.
  • ๊ธฐ๋ณธ๊ฐ’์€ undefined์ž…๋‹ˆ๋‹ค.

2. Writable

  • ์†์„ฑ์˜ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • true๋กœ ์„ค์ •๋˜๋ฉด ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, false๋กœ ์„ค์ •๋˜๋ฉด ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ๋ณธ๊ฐ’์€ false์ž…๋‹ˆ๋‹ค.

3. Enumerable

  • ์†์„ฑ์ด ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • true๋กœ ์„ค์ •๋˜๋ฉด for...in ๋ฃจํ”„๋‚˜ Object.keys()์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์†์„ฑ์„ ์—ด๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ๋ณธ๊ฐ’์€ false์ž…๋‹ˆ๋‹ค.

4. Configurable

  • ์†์„ฑ์˜ ์ •์˜๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์†์„ฑ์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • true๋กœ ์„ค์ •๋˜๋ฉด ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, false๋กœ ์„ค์ •๋˜๋ฉด ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    (๋‹จ, writable์ด true์ธ ๊ฒฝ์šฐ Value, Writable์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฑด ๊ฐ€๋Šฅ)
  • ๊ธฐ๋ณธ๊ฐ’์€ false์ž…๋‹ˆ๋‹ค.
let person = {
    name: "John"
};

Object.defineProperty(person, 'age', {
    value: 30,
    writable: true,
    enumerable: true,
    configurable: true
});
console.log(person.age); // 30

03. Accessor Property Attributes ๐Ÿ”„

Accessor Property Attributes๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์†์„ฑ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

1. Get

  • ์†์„ฑ์˜ ๊ฐ’์„ ์ฝ์„ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
  • ๊ธฐ๋ณธ๊ฐ’์€ undefined์ž…๋‹ˆ๋‹ค.

2. Set

  • ์†์„ฑ์˜ ๊ฐ’์„ ์„ค์ •ํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
  • ๊ธฐ๋ณธ๊ฐ’์€ undefined์ž…๋‹ˆ๋‹ค.
let person = {
    firstName: "John",
    lastName: "Doe",
    get fullName() {
        return `${this.firstName} ${this.lastName}`;
    },
    set fullName(name) {
        [this.firstName, this.lastName] = name.split(" ");
    }
};

console.log(person.fullName); // John Doe
person.fullName = "Jane Smith";
console.log(person.fullName); // Jane Smith

04. Property Attribute์˜ ํ™œ์šฉ๐Ÿ› ๏ธ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ Property Attributes๋Š” ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋”์šฑ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ๋งž์ถคํ™”ํ•˜๊ณ , ๋ณด์•ˆ์„ฑ ๋ฐ ์•ˆ์ •์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ Property Attributes์˜ ๋‹ค์–‘ํ•œ ํ™œ์šฉ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.
Object.defineProperty()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์†์„ฑ์„ ๋” ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1. ๋ถˆ๋ณ€ ์†์„ฑ ๋งŒ๋“ค๊ธฐ (์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ)

์†์„ฑ์˜ ๊ฐ’์„ ํ•œ ๋ฒˆ ์„ค์ •ํ•œ ํ›„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด writable ์†์„ฑ์„ false๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

const obj = {};

Object.defineProperty(obj, 'readOnly', {
  value: 'This value cannot be changed',
  writable: false,
  enumerable: true,
  configurable: true
});

console.log(obj.readOnly); // 'This value cannot be changed'
obj.readOnly = 'Trying to change value';
console.log(obj.readOnly); // ์—ฌ์ „ํžˆ 'This value cannot be changed'

2. ์—ด๊ฑฐ ๋ถˆ๊ฐ€๋Šฅํ•œ ์†์„ฑ ๋งŒ๋“ค๊ธฐ

์†์„ฑ์„ for...in ๋ฃจํ”„๋‚˜ Object.keys() ๋ฉ”์„œ๋“œ์—์„œ ์ œ์™ธ์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ enumerable ์†์„ฑ์„ false๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

const obj = {};

Object.defineProperty(obj, 'hidden', {
  value: 'This value is hidden from enumeration',
  enumerable: false,
  writable: true,
  configurable: true
});

for (let key in obj) {
  console.log(key); // ์ถœ๋ ฅ๋˜์ง€ ์•Š์Œ
}

console.log(Object.keys(obj)); // ๋นˆ ๋ฐฐ์—ด ์ถœ๋ ฅ

3. ์‚ญ์ œ ๋ถˆ๊ฐ€๋Šฅํ•œ ์†์„ฑ ๋งŒ๋“ค๊ธฐ

์†์„ฑ์„ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด configurable ์†์„ฑ์„ false๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

const obj = {};

Object.defineProperty(obj, 'permanent', {
  value: 'This value cannot be deleted',
  configurable: false,
  writable: true,
  enumerable: true
});

console.log(obj.permanent); // 'This value cannot be deleted'
delete obj.permanent;
console.log(obj.permanent); // ์—ฌ์ „ํžˆ 'This value cannot be deleted'

4. ์ ‘๊ทผ์ž ์†์„ฑ ํ™œ์šฉ

์†์„ฑ์˜ ๊ฐ’์„ ์ฝ๊ฑฐ๋‚˜ ์„ค์ •ํ•  ๋•Œ ์‚ฌ์šฉ์ž ์ •์˜ ๋กœ์ง์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด get๊ณผ set ์†์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

const obj = {};
let internalValue = 0;

Object.defineProperty(obj, 'number', {
  get() {
    return internalValue;
  },
  set(value) {
    if (typeof value === 'number' && value > 0) {
      internalValue = value;
    } else {
      console.error('Value must be a positive number');
    }
  },
  enumerable: true,
  configurable: true
});

obj.number = 42;
console.log(obj.number); // 42

obj.number = -10; // 'Value must be a positive number'
console.log(obj.number); // 42

5. ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง ๋ฐ ์บก์Šํ™”

Property Attributes๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์˜ ํŠน์ • ์†์„ฑ๋“ค์„ ๋ณดํ˜ธํ•˜๊ณ  ์บก์Šํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function Person(name, age) {
  Object.defineProperty(this, 'name', {
    value: name,
    writable: false,
    enumerable: true,
    configurable: false
  });

  let _age = age;
  Object.defineProperty(this, 'age', {
    get() {
      return _age;
    },
    set(value) {
      if (typeof value === 'number' && value > 0) {
        _age = value;
      } else {
        console.error('Invalid age value');
      }
    },
    enumerable: true,
    configurable: true
  });
}

const person = new Person('John', 30);
console.log(person.name); // 'John'
person.name = 'Doe'; // ๋ฌด์‹œ๋จ
console.log(person.name); // ์—ฌ์ „ํžˆ 'John'

person.age = 31;
console.log(person.age); // 31
person.age = -5; // 'Invalid age value'
console.log(person.age); // ์—ฌ์ „ํžˆ 31

05. ์†์„ฑ ๊ธฐ์ˆ ์ž(Property Descriptor)ํ™•์ธํ•˜๊ธฐ๐Ÿ”

์†์„ฑ ๊ธฐ์ˆ ์ž๋Š” ์†์„ฑ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
Object.getOwnPropertyDescriptor()์™€ Object.getOwnPropertyDescriptors()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†์„ฑ์˜ ์†์„ฑ๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = {
    name: "Alice"
};

let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log(descriptor);
/*
{
    value: "Alice",
    writable: true,
    enumerable: true,
    configurable: true
}
*/
728x90
๋ฐ˜์‘ํ˜•