Skip to content

Latest commit

ย 

History

History
205 lines (161 loc) ยท 12.3 KB

property_attribue.md

File metadata and controls

205 lines (161 loc) ยท 12.3 KB

๊ฐ์ฒด๋ฅผ ๋‹ค๋ฃจ๋ฉด์„œ ํ”„๋กœํผํ‹ฐ(Property)์— ๋Œ€ํ•ด ์–ด๋Š์ •๋„ ์•Œ๊ณ  ์žˆ์—ˆ์ฃ ? ์ด์ œ ๊ทธ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋œฏ์–ด๋ด…๋‹ˆ๋‹ค! ํ•˜์ง€๋งŒ ๋ฐ˜๋“œ์‹œ ์•Œ์•„์•ผ ํ•˜๋Š” ๋‚ด์šฉ์„ ๋‚ดํฌํ•˜์ง„ ์•Š์œผ๋ฏ€๋กœ, ํ•„์š”์— ์˜ํ•œ ์ฐธ์กฐ๋กœ ์ ‘๊ทผํ•ด์ฃผ์„ธ์š”.

ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ(Property Attribute)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํ”„๋กœํผํ‹ฐ์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ(Property Attribute)๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ž๋™ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ์ „์—, ๋‚ด๋ถ€ ์Šฌ๋กฏ(Internal Slot)๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ(Internal Method)์— ๋Œ€ํ•ด ์งš๊ณ  ๋„˜์–ด๊ฐ€์ฃ . ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์˜ ๊ตฌํ˜„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ECMAScript ์‚ฌ์–‘์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์˜์‚ฌ ํ”„๋กœํผํ‹ฐ(Pseudo Property)์™€ ์˜์‚ฌ ๋ฉ”์„œ๋“œ(Pseudo Method)์ž…๋‹ˆ๋‹ค.



์œ„ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์ด์ค‘ ๋Œ€๊ด„ํ˜ธ([[]])๋กœ ๊ฐ์‹ผ ์ด๋ฆ„๋“ค์ด ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ์›์น™์ ์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ์— ์ง์ ‘์ ์ธ ์ ‘๊ทผ ๋ฐ ํ˜ธ์ถœ์„ ๊ธˆ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ ์ผ๋ถ€์— ํ•œํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ˆ˜๋‹จ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋ชจ๋“  ๊ฐ์ฒด๋Š” [[Prototype]]์ด๋ผ๋Š” ๋‚ด๋ถ€ ์Šฌ๋กฏ์„ ๊ฐ–๊ณ , __proto__๋ฅผ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฒ˜๋Ÿผ์š”!

const obj = {};

obj.[[Prototype]];  // SyntaxError: Unexpected token '['
obj.__proto__;      // {constructor: ฦ’,ย โ€ฆ}

์ž, ๊ทธ๋Ÿผ ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค.

ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์™€ ๋””์Šคํฌ๋ฆฝํ„ฐ ๊ฐ์ฒด

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์ด ๊ด€๋ฆฌํ•˜๋Š” ๋‚ด๋ถ€ ์ƒํƒœ ๊ฐ’(Meta Property)์ธ ๋‚ด๋ถ€ ์Šฌ๋กฏ์ž…๋‹ˆ๋‹ค.

ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด์œ ๋Š” ์ƒ์ˆ ํ–ˆ์ฃ ? ๊ทธ๋Ÿฌ๋‚˜ Object.getOwnPropertyDescriptor ๋ฉ”์„œ๋“œ๋กœ ๊ฐ„์ ‘์ ์ธ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ํ”„๋กœํผํ‹ฐ ๋””์Šคํฌ๋ฆฝํ„ฐ(Property Descriptor) ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์š”๊ตฌํ•˜๋ฉด undefined๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

const person = {
    name : 'amy'
};
person.age = 16;
console.log(Object.getOwnPropertyDescriptors(person));
/*
{
  name: { value: 'amy', writable: true, enumerable: true, configurable: true },
  age: { value: 16, writable: true, enumerable: true, configurable: true }
}
*/

ES8์—๋Š” ๋ณต์ˆ˜์˜ ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” getOwnPropertyDescriptors ํ•จ์ˆ˜๋„ ์ถ”๊ฐ€๋˜์—ˆ์ง€๋งŒ... ์•Œ์•„๋งŒ ๋‘์„ธ์š”!

ํ”„๋กœํผํ‹ฐ๋Š” ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ(Data Property)์™€ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ(Accessor Property)๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ๋Š” ํ‚ค์™€ ๊ฐ’์œผ๋กœ ๊ตฌ์„ฑ๋˜๊ณ  ์ง€๊ธˆ๊ป ์‚ดํŽด๋ณธ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—ฌ๊ธฐ์— ํ•ด๋‹นํ•˜๋ฉฐ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์ด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ž๋™ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

    ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์„ค๋ช…
    [[Value]] โœ… ํ”„๋กœํผํ‹ฐ ํ‚ค๋ฅผ ํ†ตํ•ด ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ ‘๊ทผํ•˜๋ฉด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค.
    โœ… ํ”„๋กœํผํ‹ฐ ํ‚ค๋ฅผ ํ†ตํ•ด ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด [[Value]]์— ๊ฐ’์„ ์žฌํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์œผ๋ฉด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋™์  ์ƒ์„ฑํ•˜๊ณ  ์ƒ์„ฑ๋œ ํ”„๋กœํผํ‹ฐ [[Value]]์— ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    [[Writable]] โœ… ํ”„๋กœํผํ‹ฐ ๊ฐ’์˜ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ boolean ๊ฐ’์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.
    โœ… [[Writable]]์ด false์ธ ๊ฒฝ์šฐ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ์˜ [[Value]] ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ์ฝ๊ธฐ ์ „์šฉ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
    [[Enumerable]] โœ… ํ”„๋กœํผํ‹ฐ์˜ ์—ด๊ฑฐ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ boolean ๊ฐ’์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.
    โœ… [[Enumerable]]์˜ ๊ฐ’์ด false์ธ ๊ฒฝ์šฐ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๋Š” for ... in ์ด๋‚˜ Object.keys ๋ฉ”์„œ๋“œ ๋“ฑ์œผ๋กœ ์—ด๊ฑฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    [[Configurable]] โœ… ํ”„๋กœํผํ‹ฐ์˜ ์žฌ์ •์˜ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ boolean๊ฐ’์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.
    โœ… [[Configurable]]์˜ ๊ฐ’์ด false์ธ ๊ฒฝ์šฐ ์‚ญ์ œ๋‚˜ ๋ณ€๊ฒฝ์ด ๊ธˆ์ง€๋ฉ๋‹ˆ๋‹ค. ๋‹จ, [[Writable]]์ด true์ธ ๊ฒฝ์šฐ๋Š” [[Value]]์˜ ๋ณ€๊ฒฝ๊ณผ [[Writable]]์„ false๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋Š” ์ž์ฒด์ ์œผ๋กœ ๊ฐ’์„ ๊ฐ–์ง€ ์•Š์œผ๋‚˜ ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ์ฝ๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ์ ‘๊ทผ์ž ํ•จ์ˆ˜(Accessor Function)๋กœ ๊ตฌ์„ฑ๋œ ํ”„๋กœํผํ‹ฐ์ž…๋‹ˆ๋‹ค. ์ ‘๊ทผ์ž ํ•จ์ˆ˜๋Š” getter/setter ํ•จ์ˆ˜๋ผ๊ณ ๋„ ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

    ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์„ค๋ช…
    [[Get]] โœ… ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ฝ์„ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ์ ‘๊ทผ์ž ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
    โœ… ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ํ”„๋กœํผํ‹ฐ ๊ฐ’์— ์ ‘๊ทผํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ [[Get]]์˜ ๊ฐ’, getter ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ํ”„๋กœํผํ‹ฐ ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.
    [[Set]] โœ… ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ์ €์žฅํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ์ ‘๊ทผ์ž ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
    โœ… ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ €์žฅํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ [[Set]]๊ฐ’, ์ฆ‰ setter ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ํ”„๋กœํผํ‹ฐ ๊ฐ’์œผ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
    [[Enumerable]] โœ… ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์˜ enumerable๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    [[Configurable]] โœ… ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์˜ configurable๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋กœ ํ”„๋กœํผํ‹ฐ ๊ฐ’์— ์ ‘๊ทผํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ์š”?
      • 1๏ธโƒฃ ํ”„๋กœํผํ‹ฐ ํ‚ค๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ ํ‚ค๋Š” ๋ฌธ์ž์—ด์ด๊ฑฐ๋‚˜ ์‹ฌ๋ณผ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      • 2๏ธโƒฃ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
      • 3๏ธโƒฃ ๊ฒ€์ƒ‰๋œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์ธ์ง€ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
      • 4๏ธโƒฃ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์˜ ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ [[Get]]์˜ ๊ฐ’์ธ getter๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ž ๊น, ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ?

  • ์–ด๋ ค์šด ๋‹จ์–ด๊ฐ€ ๋‚˜์™”๋„ค์š”? ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์ด๋ผ๋‹ˆ. ํ”„๋กœํ† ํƒ€์ž…(Prototype)์€ ์–ด๋–ค ๊ฐ์ฒด์˜ ์ƒ์œ„(๋ถ€๋ชจ) ๊ฐ์ฒด ์—ญํ• ์„ ํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋กœํ† ํƒ€์ž…์„ ํ†ตํ•ด ์šฐ๋ฆฌ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋žจ์ฒ˜๋Ÿผ ์ƒ์†๊ณผ ํ™•์žฅ์„ ํ•  ์ˆ˜ ์žˆ์ฃ . ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ(Prototype Chain)์€ ํ”„๋กœํ† ํƒ€์ž…์ด ๋‹จ๋ฐฉํ–ฅ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ(Linked List)๋กœ ์—ฐ๊ฒฐ๋œ ์ƒ์† ๊ตฌ์กฐ๋ฅผ ๋œปํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœํผํ‹ฐ ์ •์˜

์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ •์˜ํ•˜๊ฑฐ๋‚˜, ๊ธฐ์กด ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Object.defineProperty ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const person = {};

Object.defineProperty(person, 'firstName', {
    value : 'Chil',
    writable : true,
    enumerable : true,
    configurable : true
})

Object.defineProperty(person, 'lastName', {
    value : 'Amy',
})

let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log('firstName', descriptor);
// firstName {
//   value: 'Chil',
//   writable: true,
//   enumerable: true,
//   configurable: true
// }

descriptor = Object.getOwnPropertyDescriptor(person, 'lastName');
console.log('lastName', descriptor);
// lastName {
//   value: 'Amy',
//   writable: false,
//   enumerable: false,
//   configurable: false
// }
console.log(Object.keys(person));
//[ 'firstName' ]
person.lastName = "J";
delete person.lastName;

descriptor = Object.getOwnPropertyDescriptor(person, 'lastName');
console.log('lastName', descriptor);
// lastName {
//   value: 'Amy',
//   writable: false,
//   enumerable: false,
//   configurable: false
// }
Object.defineProperty(person, 'fullName', {
    get() {
        return `${this.firstName} ${this.lastName}`
    }
    set(name){
        [this.firstName, this.lastName] = name.split(' ');
    }
    enumberable : true,
    configurable : true
});

descriptor = Object.getOwnPropertyDescriptor(person, 'fullName');
console.log(descriptor);
// {
//   get: [Function: get],
//   set: [Function: set],
//   enumerable: false,
//   configurable: true
// }
person.fullName = "thin Amy";
console.log(person);
// { firstName: 'thin' }

ํ”„๋กœํผํ‹ฐ ๋””์Šคํฌ๋ฆฝํ„ฐ ๊ฐ์ฒด์—์„œ ์ƒ๋žต๋œ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ๊ฐ’์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

ํ”„๋กœํผํ‹ฐ ๋””์Šคํฌ๋ฆฝํ„ฐ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ๋Œ€์‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์ƒ๋žตํ–ˆ์„ ๋•Œ์˜ ๊ธฐ๋ณธ๊ฐ’
value [[Value]] undefined
get [[Get]] undefined[
set [[Set]] undefined
writable [[Writable]] false
enumerable [[Enumerable]] false
configurable [[Configurable]] false

๋ณต์ˆ˜์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ •์˜ํ•˜๋Š” defineProperties ํ•จ์ˆ˜๋„ ์กด์žฌํ•˜์ง€๋งŒ... ์•Œ์•„๋งŒ ๋‘์„ธ์š”!


๊ฐ์ฒด ๋ณ€๊ฒฝ ๋ฐฉ์ง€

๊ฐ์ฒด๋Š” ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๊ฐ’์ด๋ฏ€๋กœ ์žฌํ• ๋‹น ์—†์ด ์ง์ ‘ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ์š”?

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ฐ์ฒด ๋ณ€๊ฒฝ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ตฌ๋ถ„ ๋ฉ”์„œ๋“œ ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€ ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ ํ”„๋กœํผํ‹ฐ ๊ฐ’ ์ฝ๊ธฐ ํ”„๋กœํผํ‹ฐ ๊ฐ’ ์“ฐ๊ธฐ ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์žฌ์ •์˜
๊ฐ์ฒด ํ™•์žฅ ๊ธˆ์ง€ Object.preventExtensions X O O O O
๊ฐ์ฒด ๋ฐ€๋ด‰ Object.seal X X O O X
๊ฐ์ฒด ๋™๊ฒฐ Object.freeze X X O X X

์ถ”๊ฐ€์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” Object.freeze ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

function deepFreeze(target){
    if(target && typeof target === 'object' && !Object.isFrozen(target)){
        Object.freeze(target);
        Object.keys(target).forEach(key => deepFreeze(target[key]));
    }
}
const person = {
    name : 'Amy',
    address: {city : 'LA'}
};

deepFreeze(person)
console.log(Object.isFrozen(person));         // true
console.log(Object.isFrozen(person.address)); // true

person.address.city = 'Seoul';
console.log(person);                          // {name: 'Amy', address: {city: 'Seoul'}}