# [๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ] - ๊ฐ์ฒด(Object)
Study Repository

[๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ] - ๊ฐ์ฒด(Object)

by rlaehddnd0422

[๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ]๋Š” ์•„๋ž˜ ํŠœํ† ๋ฆฌ์–ผ ๊ณผ์ •์„ ๋ฐ”ํƒ•์œผ๋กœ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

๊ฐ์ฒด: ๊ธฐ๋ณธ

 

ko.javascript.info

 

๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ์„ค์ •

 

ko.javascript.info

 

์ด๋ฒˆ์—๋Š” ์ด์ „ ํฌ์ŠคํŒ…์˜ ์ž๋ฃŒํ˜• ํŒŒํŠธ์—์„œ ์งง๊ฒŒ ์„ค๋ช…ํ–ˆ๋˜ "๊ฐ์ฒด"์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ด…์‹œ๋‹ค.


1. ๊ฐ์ฒด

๊ฐ์ฒดํ˜• ํƒ€์ž…์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ 7๊ฐ€์ง€ ํƒ€์ž…๋“ค์€ ํ•˜๋‚˜์˜ ๋ณ€์ˆ˜์— ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ๋งŒ ๋‹ด์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์œ ํ˜•๋“ค์„ ์›์‹œ(primitive) ํƒ€์ž…์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ์ฒดํ˜•์€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๋ณ€์ˆ˜์— ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด ํƒ€์ž…์—๋Š” key๋กœ ๊ตฌ๋ถ„๋œ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์ด๋‚˜ ๋ณต์žกํ•œ ๊ฐœ์ฒด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž˜ ๋‹ค๋ฃจ๋ ค๋ฉด ์ด ๊ฐ์ฒด๋ฅผ ์ž˜ ์ดํ•ดํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๊ฐ์ฒด๋Š” ์ค‘๊ด„ํ˜ธ {}๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋งŒ๋“ค๊ฑฐ๋‚˜ new Object()๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

let user = new Object(); // '๊ฐ์ฒด ์ƒ์„ฑ์ž' ๋ฌธ๋ฒ•
let user = {};  // '๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด' ๋ฌธ๋ฒ•, ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ์ฃผ๋กœ ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•จ

 

์ค‘๊ด„ํ˜ธ ์•ˆ์—๋Š” 'key-value'์Œ์œผ๋กœ ๊ตฌ์„ฑ๋œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š”๋ฐ, "key"์—๋Š” ๋ฌธ์žํ˜•, "value"์—๋Š” ๋ชจ๋“  ์ž๋ฃŒํ˜•์ด ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ค‘๊ด„ํ˜ธ๋กœ ๋‘˜๋Ÿฌ์‹ธ์ธ ๊ฐ์ฒดํ˜•๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.)

let user = {     // ๊ฐ์ฒด
  name: "John",  // ํ‚ค: "name",  ๊ฐ’: "John"
  age: 30,        // ํ‚ค: "age", ๊ฐ’: 30
  "likes birds" : true // ํ‚ค : likes birds, ๊ฐ’ : true
};

 

์ด ๋•Œ ์ฃผ์˜ํ•  ์ ์œผ๋กœ๋Š” ์„ธ ๋ฒˆ์งธ ํ”„๋กœํผํ‹ฐ์™€ ๊ฐ™์ด ๊ณต๋ฐฑ๊ธ€์ž๊ฐ€ ํฌํ•จ๋œ key๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํฐ ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ €๋Ÿฌ๋ผ๊ณ  ๋งŒ๋“  ๊ธฐ๋Šฅ์€ ์•„๋‹Œ ๊ฒƒ ๊ฐ™๋„ค์š”. ํ•˜๋‚˜์˜ ์˜ˆ์‹œ์ผ๋ถ„ ์›ฌ๋งŒํ•˜๋ฉด ์–ธ๋”์Šค์ฝ”์–ด ์”์‹œ๋‹ค

 

์™ธ๋ถ€์—์„œ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋ ๊นŒ์š”? ์ž๋ฐ”์ฒ˜๋Ÿผ ์  ํ‘œ๊ธฐ๋ฒ•(dot notation)์„ ์ด์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ ํšจํ•œ ๋ณ€์ˆ˜ ์‹๋ณ„์ž๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ์—” ์  ํ‘œ๊ธฐ๋ฒ• ๋Œ€์‹  ๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

// ํ”„๋กœํผํ‹ฐ ๊ฐ’ ์–ป๊ธฐ
alert( user.name ); // John
alert( user.age ); // 30

alert( user.full name ); // error
alert(user["full name"]);

 

๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ๊ทธ๋ƒฅ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

user.isAdmin = true;
user["likes birds"] = true;

 

ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ๋Š”์š”? delete ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์‰ฝ๋„ค์š”

delete user.age;
delete user["likes birds"];

 

๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ•

๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ํ‘œํ˜„์‹์˜ ํ‰๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let key = "likes birds";

// user["likes birds"] = true; ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
user[key] = true;

 

๋ณ€์ˆ˜ key๋Š” ๋Ÿฐํƒ€์ž„์— ํ‰๊ฐ€๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’ ๋ณ€๊ฒฝ ๋“ฑ์— ๋”ฐ๋ผ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒฝ์šฐ๋“ , ํ‰๊ฐ€๊ฐ€ ๋๋‚œ ์ดํ›„์˜ ๊ฒฐ๊ณผ๊ฐ€ ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์‘์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = {
  name: "John",
  age: 30
};

let key = prompt("์‚ฌ์šฉ์ž์˜ ์–ด๋–ค ์ •๋ณด๋ฅผ ์–ป๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”?", "name");

// ๋ณ€์ˆ˜๋กœ ์ ‘๊ทผ
alert( user[key] ); // John (ํ”„๋กฌํ”„ํŠธ ์ฐฝ์— "name"์„ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ)

 

ํ•˜์ง€๋งŒ ์•„๋ž˜์™€ ๊ฐ™์ด ์  ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ๋Š” ์ด๋Ÿฐ ๋ฐฉ์‹์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 

let user = {
  name: "John",
  age: 30
};

let key = "name";
alert( user.key ) // undefined

 

๊ณ„์‚ฐ๋œ ํ”„๋กœํผํ‹ฐ

์ด๋ ‡๊ฒŒ ํ”„๋กœํผํ‹ฐ ํ‚ค๋ฅผ ๋Œ€๊ด„ํ˜ธ๋กœ ๋‘˜๋Ÿฌ์‹ธ๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ "๊ณ„์‚ฐ๋œ ํ”„๋กœํผํ‹ฐ" ๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ์š”. ๋ฐ˜๋Œ€๋กœ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

let fruit = prompt("์–ด๋–ค ๊ณผ์ผ์„ ๊ตฌ๋งคํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "apple");

let bag = {
  [fruit]: 5, // ๋ณ€์ˆ˜ fruit์—์„œ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์„ ๋™์ ์œผ๋กœ ๋ฐ›์•„ ์˜ต๋‹ˆ๋‹ค.
};

alert( bag.apple ); // fruit์— "apple"์ด ํ• ๋‹น๋˜์—ˆ๋‹ค๋ฉด, 5๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

 

๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ•์€ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„๊ณผ ๊ฐ’์˜ ์ œ์•ฝ์„ ์—†์• ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์  ํ‘œ๊ธฐ๋ฒ•๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ž‘์„ฑํ•˜๊ธฐ ๋ฒˆ๊ฑฐ๋กญ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์ด ํ™•์ •๋œ ์ƒํ™ฉ์ด๊ณ , ๋‹จ์ˆœํ•œ ์ด๋ฆ„์ด๋ผ๋ฉด ์ฒ˜์Œ์—” ์  ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋‹ค๊ฐ€ ๋ญ”๊ฐ€ ๋ณต์žกํ•œ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๋‹จ์ถ• ํ”„๋กœํผํ‹ฐ

์‹ค๋ฌด์—์„  ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ๊ธฐ์กด ๋ณ€์ˆ˜์—์„œ ๋ฐ›์•„์™€ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

function makeUser(name, age) {
  return {
    name: name,
    age: age,
    // ...๋“ฑ๋“ฑ
  };
}

let user = makeUser("John", 30);
alert(user.name); // John

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

function makeUser(name, age) {
  return {
    name, // name: name ๊ณผ ๊ฐ™์Œ
    age,  // age: age ์™€ ๊ฐ™์Œ
    // ...
  };
}

 

ํ•œ ๊ฐ์ฒด์—์„œ ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ์™€ ๋‹จ์ถ• ํ”„๋กœํผํ‹ฐ๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

let user = {
  name,  // name: name ๊ณผ ๊ฐ™์Œ
  age: 30
};

 

ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์—๋Š” ์ œ์•ฝ ์‚ฌํ•ญ์ด ์—†๋‹ค. 

๋ณ€์ˆ˜๋ช…์—๋Š” ์˜ˆ์•ฝ์–ด๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ œ์•ฝ์‚ฌํ•ญ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค์ฃ . ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์˜ˆ์•ฝ์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

// ์˜ˆ์•ฝ์–ด๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•ด๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.
let obj = {
  for: 1,
  let: 2,
  return: 3
};

alert( obj.for + obj.let + obj.return );  // 6
  • ์˜ˆ์•ฝ์–ด ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ˆซ์žํ˜• ๊ฐ’, ๋ฌธ์žํ˜• ๊ฐ’, ์‹ฌ๋ณผํ˜• ๊ฐ’(๋’ค์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •)๋„ ํ”„๋กœํผํ‹ฐ์˜ ํ‚ค๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ˆซ์žํ˜• ๊ฐ’์„ ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฌธ์ž์—ด๋กœ ์ž๋™๋ณ€ํ™˜ ๋ฉ๋‹ˆ๋‹ค. 0 -> "0"
    • alert( obj["0"] ); // test
    • alert( obj[0] ); // test (๋™์ผํ•œ ํ”„๋กœํผํ‹ฐ)

์ด์™€๊ฐ™์ด ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ํ‚ค์— ์“ธ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ž์—ด์—” ์ œ์•ฝ์ด ์—†์ง€๋งŒ, ์—ญ์‚ฌ์ ์ธ ์ด์œ  ๋•Œ๋ฌธ์— ํŠน๋ณ„ ๋Œ€์šฐ๋ฅผ ๋ฐ›๋Š” ์ด๋ฆ„์ด ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ฐ”๋กœ, __proto__์ž…๋‹ˆ๋‹ค.

let obj = {};
obj.__proto__ = 5; // ์ˆซ์ž๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
alert(obj.__proto__); // [object Object] - ์ˆซ์ž๋ฅผ ํ• ๋‹นํ–ˆ์ง€๋งŒ ๊ฐ’์€ ๊ฐ์ฒด๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜๋„ํ•œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋„ค์š”.

 

__proto__์˜ ๋ณธ์งˆ์€ "ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†"์—์„œ, ์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„์ง€์— ๋Œ€ํ•ด์„  ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ์™€ __proto__๊ฐ€ ์—†๋Š” ๊ฐ์ฒด์—์„œ ์ž์„ธํžˆ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

 

‘in’ ์—ฐ์‚ฐ์ž๋กœ ํ”„๋กœํผํ‹ฐ ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธํ•˜๊ธฐ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž๋ฐ”์™€ ๋‹ค๋ฅธ์ ์€ ๊ฐ์ฒด์— ์ฐพ๊ณ ์ž ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  "undefined๋ฅผ ๋ฆฌํ„ด"ํ•œ๋‹ค๋Š” ์ ์ธ๋ฐ์š”. ์ด๋Ÿฐ ํŠน์ง•์„ ์‚ด๋ ค ํ”„๋กœํผํ‹ฐ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

alert( user.noSuchProperty === undefined ); // true๋Š” 'ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Œ'์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์œ„์ฒ˜๋Ÿผ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ in ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = { name: "John", age: 30 };

/**
์ด ๋•Œ ๋ฐ˜๋“œ์‹œ 
1. in ์™ผ์ชฝ์—” ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์„ ๋ฌธ์ž์—ด๋กœ ๊ฐ์‹ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
2. 
*/
alert( "age" in user ); // user.age๊ฐ€ ์กด์žฌํ•˜๋ฏ€๋กœ true๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
alert( "blabla" in user ); // user.blabla๋Š” ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— false๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

 

== undefined๋กœ ํ™•์ธํ•˜๋Š” ๊ฒƒ๊ณผ in์œผ๋กœ ํ™•์ธํ•˜๋Š” ๊ฒƒ์€ ๋ฌด์Šจ ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ์š”?

๋งŒ์•ฝ ์•„๋ž˜์™€ ๊ฐ™์ด ํ”„๋กœํผํ‹ฐ๋Š” ์กด์žฌํ•˜๋Š”๋ฐ, ๊ฐ’์— undefined๊ฐ€ ํ• ๋‹น๋œ ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณด๋ฉด in์„ ์“ฐ๋Š” ๊ฒƒ์ด ํ”„๋กœํผํ‹ฐ ์กด์žฌ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ธฐ์— ๋” ์ ํ•ฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋Š๋ผ์‹ค ์ˆ˜ ์žˆ์œผ์‹ค ๊ฒ๋‹ˆ๋‹ค.

let obj = {
  test: undefined
};

alert( obj.test == undefined ); // ๊ฐ’์ด `undefined`์ด๋ฏ€๋กœ, true. 
// ํ•˜์ง€๋งŒ ์กด์žฌ์—ฌ๋ถ€๋กœ ํŒ๋‹จํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ test ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์ด undefined์ธ ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•œ ๊ฒƒ์ด๋ฏ€๋กœ ์ •ํ™•ํ•˜์ง€ X

alert( "test" in obj ); // `in`์„ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ์œ ๋ฌด๋ฅผ ์ œ๋Œ€๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(true๊ฐ€ ์ถœ๋ ฅ๋จ).

 

for...in ๋ฐ˜๋ณต๋ฌธ

for..in ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ‚ค๋ฅผ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. for..in์€ for(;;) ๋ฐ˜๋ณต๋ฌธ๊ณผ๋Š” ์™„์ „ํžˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

 

let user = {
  name: "John",
  age: 30,
  isAdmin: true
};

for (let key in user) {
  // ํ‚ค
  alert( key );  // name, age, isAdmin
  // ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’
  alert( user[key] ); // John, 30, true
}

 

๋ฒˆ์™ธ : ํ”„๋กœํผํ‹ฐ์—๋Š” ์ˆœ์„œ๊ฐ€ ์žˆ์„๊นŒ?

๊ฐ์ฒด๋Š” ํŠน๋ณ„ํ•œ ๋ฐฉ์‹์œผ๋กœ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. ์ •์ˆ˜ ํ”„๋กœํผํ‹ฐ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ž๋™์œผ๋กœ ์ •๋ ฌ๋˜๊ณ  ๊ทธ ์™ธ์˜ ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒด์— ์ถ”๊ฐ€ํ•œ ์ˆœ์„œ ๊ทธ๋Œ€๋กœ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ด…์‹œ๋‹ค.

  • ์ฐธ๊ณ ๋กœ ์ •์ˆ˜ ํ”„๋กœํผํ‹ฐ๋ž€ ๋ฌธ์ž์—ด->์ˆซ์žํ˜•, ์ˆซ์žํ˜•->๋ฌธ์ž์—ด๋กœ ๊ฐ’์˜ ๋ณ€ํ˜•์—†์ด ์™”๋‹ค๊ฐ”๋‹ค ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งํ•จ.
    • alert( String(Math.trunc(Number("49"))) ); // '49'๊ฐ€ ์ถœ๋ ฅ. ๊ธฐ์กด์— ์ž…๋ ฅํ•œ ๊ฐ’๊ณผ ๊ฐ™์œผ๋ฏ€๋กœ ์ •์ˆ˜ ํ”„๋กœํผํ‹ฐ์ž„.
    • alert( String(Math.trunc(Number("+49"))) ); // '49'๊ฐ€ ์ถœ๋ ฅ. ๊ธฐ์กด์— ์ž…๋ ฅํ•œ ๊ฐ’(+49)๊ณผ ๋‹ค๋ฅด๋ฏ€๋กœ ์ •์ˆ˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋‹˜
    • alert( String(Math.trunc(Number("1.2"))) ); // '1'์ด ์ถœ๋ ฅ. ๊ธฐ์กด์— ์ž…๋ ฅํ•œ ๊ฐ’(1.2)๊ณผ ๋‹ค๋ฅด๋ฏ€๋กœ ์ •์ˆ˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹˜
let codes = {
  "49": "๋…์ผ",
  "41": "์Šค์œ„์Šค",
  "44": "์˜๊ตญ",
  // ..,
  "+1": "๋ฏธ๊ตญ"
};

for (let code in codes) {
  alert(code); // 41, 44, 49, 1
}
let user = {
  name: "John",
  surname: "Smith"
};
user.age = 25; // ํ”„๋กœํผํ‹ฐ๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

// ์ •์ˆ˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹Œ ํ”„๋กœํผํ‹ฐ๋Š” ์ถ”๊ฐ€๋œ ์ˆœ์„œ๋Œ€๋กœ ๋‚˜์—ด๋ฉ๋‹ˆ๋‹ค.
for (let prop in user) {
  alert( prop ); // name, surname, age
}

 

๋ฒˆ์™ธ : ์ƒ์ˆ˜ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

const user = {
  name: "John"
};

user.name = "Pete"; // (*)

alert(user.name); // Pete
  • const๋Š” user์˜ ๊ฐ’์„ ๊ณ ์ •ํ•œ ๊ฒƒ์ด์ง€, ๊ทธ๊ฒŒ user์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ณ ์ •ํ•œ ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ user = ~~;์™€ ๊ฐ™์ด 'user' ๊ทธ ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ, ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฑด๋“ ๋‹ค๊ณ  ํ•ด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

 


2. ์ฐธ์กฐ์— ์˜ํ•œ ๊ฐ์ฒด ๋ณต์‚ฌ

์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ์—์„œ ์›์‹œํƒ€์ž…์€ call by value, ๊ฐ์ฒดํƒ€์ž…์€ call by reference ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, ์›์‹œํƒ€์ž…์˜ ๊ฒฝ์šฐ ๋ณต์‚ฌํ–ˆ์„ ๊ฒฝ์šฐ "๊ฐ’" ์ž์ฒด๊ฐ€ ๋ณต์‚ฌ๋˜๋ฏ€๋กœ ๊ฐ’์˜ ๋ณ€๊ฒฝ์ด ์ด๋ฃจ์–ด์ง„๋‹ค๊ณ  ํ•ด์„œ ๋ณต์‚ฌ๋œ ๊ฐ์ฒด๊นŒ์ง€ ๋ณ€๊ฒฝ๋˜์ง„ ์•Š๋Š”๋‹ค๋Š” ๋ง์ž…๋‹ˆ๋‹ค. ์•„๋ž˜๊ฐ€ ๊ทธ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

let a = 1;
let b = a;

console.log(a); // 1
console.log(b); // 1

a = 2;
console.log(a); // 2
console.log(b); // 1

 

๋ฐ˜๋ฉด, ๊ฐ์ฒด๋Š” call by reference ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— "์ฃผ์†Œ"๊ฐ€ ๋ณต์‚ฌ๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณต์‚ฌ๊ฐ€ ์ด๋ฃจ์–ด์ ธ, ์›๋ณธ๊ฐ์ฒด๊ฐ€ ๋ฐ”๋€๋‹ค๋ฉด ๋ณต์‚ฌ๊ฐ์ฒด๋„ ๋ฐ”๋€Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

let a = {
    name : 'kim'
}

let b = a;

console.log(a.name); // kim
console.log(b.name); // kim

a.name = 'park';
console.log(a); // park
console.log(b); // park

 

๊ฐ์ฒด ๋ณต์‚ฌ, ๋ณ‘ํ•ฉ, Object.assign

๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ์ฒด๋ฅผ ๋…๋ฆฝ๋œ ๊ฐ์ฒด๋กœ ๋ณต์ œํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ๊ฐ์ฒด๋ฅผ ๋…๋ฆฝ๋œ ๊ฐ์ฒด๋กœ ๋ณต์‚ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์žˆ์Šต๋‹ˆ๋‹ค๋งŒ, ๊ฝค๋‚˜ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿด ์ผ๋„ ์ž˜ ์—†๊ตฌ์š”.

 

iterateํ•˜์—ฌ key ๋ณต์‚ฌ

let user = {
  name: "John",
  age: 30
};

let clone = {}; // ์ƒˆ๋กœ์šด ๋นˆ ๊ฐ์ฒด

// ๋นˆ ๊ฐ์ฒด์— user ํ”„๋กœํผํ‹ฐ ์ „๋ถ€๋ฅผ ๋ณต์‚ฌํ•ด ๋„ฃ์Šต๋‹ˆ๋‹ค.
for (let key in user) {
  clone[key] = user[key];
}

// ์ด์ œ clone์€ ์™„์ „ํžˆ ๋…๋ฆฝ์ ์ธ ๋ณต์ œ๋ณธ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
clone.name = "Pete"; // clone์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

alert( user.name ); // ๊ธฐ์กด ๊ฐ์ฒด์—๋Š” ์—ฌ์ „ํžˆ John์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

Object.assgin ์‚ฌ์šฉ

Object.assign(dest, [src1, src2, src3...])
  • ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜ dest๋Š” ๋ณต์‚ฌ๋  ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.
  • ์ด์–ด์ง€๋Š” ์ธ์ˆ˜ src1, ..., srcN๋Š” ๋ณต์‚ฌํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ...์€ ํ•„์š”์— ๋”ฐ๋ผ ์–ผ๋งˆ๋“ ์ง€ ๋งŽ์€ ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ

let user = { name: "John" };

let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

// permissions1๊ณผ permissions2์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ user๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
Object.assign(user, permissions1, permissions2);

// now user = { name: "John", canView: true, canEdit: true }

 

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— ๊ฐ์ฒด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

let user = {
    name: "John",
    sizes: {
        height: 182,
        width: 50
      }
};

let k = {};
Object.assign(k, user);

user.sizes.height = 10;
console.log(k.sizes.height); // 10

์ด ๊ฒฝ์šฐ์—๋Š” sizes ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒดํ˜•์ด๊ธฐ ๋•Œ๋ฌธ์— call by reference๋กœ ๋ณต์‚ฌ๊ฐ€ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ์ฆ‰, user์˜ sizes์— ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋ฉด k์˜ sizes์—๋„ ๋™์ผํ•˜๊ฒŒ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๊ฒŒ ๋˜์ฃ .

 

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” 1๋ฒˆ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ๊ฐ’์„ ๊ฒ€์‚ฌํ•˜๋ฉด์„œ ๊ทธ ๊ฐ’์ด ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ ๊ฐ์ฒด์˜ ๊ตฌ์กฐ๋„ call by value๋กœ ๋ณต์‚ฌํ•ด์ฃผ๋Š” "๊นŠ์€ ๋ณต์‚ฌ" ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

_.cloneDeep(obj) 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ lodash์˜ ๋ฉ”์„œ๋“œ์ธ _.cloneDeep(obj)์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ ๋„ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์ฒ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let _ = require('lodash');

let user = {
    name: "John",
    sizes: {
        height: 182,
        width: 50
      }
};

let k = _.cloneDeep(user);
user.sizes.height = 100;
console.log(k.sizes.height); // 182

3. ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜

์ž๋ฐ”์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋„ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. Java๋Š” ์ฃผ๋กœ ์„œ๋ฒ„๋‚˜ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, JVM์„ ํ†ตํ•œ ์„ธ๋Œ€๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ฐ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๊ธฐ๋ฒ•์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด JavaScript๋Š” ๋ธŒ๋ผ์šฐ์ €๋‚˜ Node.js์™€ ๊ฐ™์€ ๋น„๋™๊ธฐ ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, ๋น„๊ต์  ๊ฐ„๋‹จํ•œ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

JS์—์„œ๋Š” "๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ"์ด๋ผ๋Š” ๊ฐœ๋…์„ ์‚ฌ์šฉํ•ด ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. "๋„๋‹ฌ ๊ฐ€๋Šฅํ•˜๋‹ค"๋Š” ๊ฐ’์€ ์‰ฝ๊ฒŒ ๋งํ•ด ์–ด๋–ป๊ฒŒ๋“  ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ ๊ฐ’์„ ์˜๋ฏธํ•˜๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ์—๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์‚ญ์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 

 

์•„๋ž˜ ๊ฐ’๋“ค์€ ํƒœ์ƒ๋ถ€ํ„ฐ "๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ๊ฐ’"๋“ค์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์‚ญ์ œ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•ฉ์‹œ๋‹ค.

  • ํ˜„์žฌ ํ•จ์ˆ˜์˜ ์ง€์—ญ๋ณ€์ˆ˜์™€ ๋งค๊ฐœ๋ณ€์ˆ˜
  • ์ค‘์ฒฉ ํ•จ์ˆ˜์˜ ์ฒด์ธ์— ์žˆ๋Š” ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜, ๋ณ€์ˆ˜
  • ์ „์—ญ ๋ณ€์ˆ˜ 

์ด๋Ÿฐ ๊ฐ’๋“ค์€ "root"๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. 

 

๊ทธ๋ ‡๋‹ค๋ฉด "๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š”" ๊ฐ’์€ ๋ฌด์—‡์ผ๊นŒ์š”? ์˜ˆ์‹œ๋กœ ์‚ดํŽด๋ด…์‹œ๋‹ค.

// user์—” ๊ฐ์ฒด ์ฐธ์กฐ ๊ฐ’์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
let user = {
  name: "John"
};

user = null;

// ์ž, ์ด์ œ "John"์€ ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ์ƒํƒœ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

user์— null ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ์ˆœ๊ฐ„๋ถ€ํ„ฐ๋Š” user.name์— ์ ‘๊ทผํ•  ๋„๋ฆฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. user์„ ๋ณต์‚ฌํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด์š”. "๋„๋‹ฌํ•  ์ˆ˜ ์—†๋‹ค"๋Š” ์˜๋ฏธ๊ฐ€ ์ดํ•ด๊ฐ€ ๋˜์…จ๋‚˜์š”? 

 

JS์—์„œ๋Š” ๋ฃจํŠธ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ์ด๋ฅผ mark(๊ธฐ์–ต)ํ•˜๋ฉฐ, ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฃจํŠธ๊ฐ€ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  ๊ฐ์ฒด๋“ค ๋˜ํ•œ ๋ฐฉ๋ฌธํ•˜๊ณ  ์ด๊ฒƒ๋“ค์„ markํ•ฉ๋‹ˆ๋‹ค. mark๋œ ๊ฐ์ฒด๋“ค์ด ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋“ค๋„ mark ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฐ์ฒด๋“ค์„ ๊ฐ ํ•œ๋ฒˆ์”ฉ ๋ฐฉ๋ฌธ(๋ฐฉ๋ฌธํ–ˆ๋˜ ๊ฐ์ฒด๋ฅผ ๋‹ค์‹œ markํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์—†์Œ)ํ•˜๋ฉฐ, ๊ฐ์ฒด๊ฐ€ ์—ฌ์ „ํžˆ ์‚ฌ์šฉ ์ค‘์ธ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด๋ฅผ '๋งˆํฌ'ํ•˜๊ณ , ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋Š” '์Šค์œ•' ๊ณผ์ •์„ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.  

 

์ด๋Ÿฐ ๋ฐฉ์‹์„ Mark-And-Sweep ๋ฐฉ์‹์ด๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

 

๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•ด ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ณ  ์‹ถ์œผ์‹œ๋‹ค๋ฉด ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜

 

ko.javascript.info


4. ๋ฉ”์†Œ๋“œ์™€ this

JS์—์„œ๋„ ๋‹น์—ฐํžˆ ๊ฐ์ฒด์—๋„ ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = {
    name: "John",
    age: 30,
    bye : function() {
        console.log(this.name + " : ์•ˆ๋…•ํžˆ ๊ณ„์„ธ์š”.");
    }
  };
  
  user.sayHi = function() {
    console.log("์•ˆ๋…•ํ•˜์„ธ์š”!");
  };

  user.sayHi();
  user.bye();

 

๋ฉ”์†Œ๋“œ ๋‹จ์ถ• ๊ตฌ๋ฌธ

๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ์•ˆ์— ๋ฉ”์†Œ๋“œ๋ฅผ ์„ ์–ธํ• ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ์ถ• ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค.

// ์•„๋ž˜ ๋‘ ๊ฐ์ฒด๋Š” ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

user = {
  sayHi: function() {
    alert("Hello");
  }
};

// ๋‹จ์ถ• ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋‹ˆ ๋” ๊น”๋”ํ•ด ๋ณด์ด๋„ค์š”.
user = {
  sayHi() { // "sayHi: function()"๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
    alert("Hello");
  }
};

 

์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•๊ณผ ๋‹จ์ถ• ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•์ด ์™„์ „ํžˆ ๋™์ผํ•˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด ์ƒ์†๊ณผ ๊ด€๋ จ๋œ ๋ฏธ๋ฌ˜ํ•œ ์ฐจ์ด๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ ์ง€๊ธˆ์œผ๋กœ์„  ์ด ์ฐจ์ด๊ฐ€ ์ค‘์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋„˜์–ด๊ฐ€๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

this

๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ this ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ ์  ์•ž์˜ this๋Š” ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์‚ฌ์šฉ๋œ ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด์ฃ .

let user = {
  name: "John",
  age: 30,

  sayHi() {
    // 'this'๋Š” 'ํ˜„์žฌ ๊ฐ์ฒด'๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
    alert(this.name);
  }

};

user.sayHi(); // John

 

user.sayHi()๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ์— this๋Š” user๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
this๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•ด ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

let user = {
  name: "John",
  age: 30,

  sayHi() {
    alert( user.name ); // Error: Cannot read property 'name' of null
  }

};


let admin = user;
user = null; // user๋ฅผ null๋กœ ๋ฎ์–ด์”๋‹ˆ๋‹ค.

admin.sayHi(); // sayHi()๊ฐ€ ์—‰๋šฑํ•œ ๊ฐ์ฒด๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. user๋ฅผ ๋ณต์‚ฌํ•ด ๋‹ค๋ฅธ ๋ณ€์ˆ˜์— ํ• ๋‹น(admin = user)ํ•˜๊ณ , user๋Š” ์ „ํ˜€ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ๋ฎ์–ด์ผ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. sayHi()๋Š” ์›์น˜ ์•Š๋Š” ๊ฐ’(null)์„ ์ฐธ์กฐํ•  ๊ฒ๋‹ˆ๋‹ค. user.name๋Œ€์‹  this.name์„ ์ธ์ˆ˜๋กœ ๋ฐ›์•˜๋‹ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒ ์ฃ .

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ this๋Š” ๋‹ค๋ฅธ ์–ธ์–ด์˜ this์™€ ๋™์ž‘๋ฐฉ์‹์ด ์กฐ๊ธˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ๋ชจ๋“  ํ•จ์ˆ˜์— this๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์•„๋ž˜์ฒ˜๋Ÿผ ์ž‘์„ฑํ•ด๋„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

function sayHi() {
  alert( this.name );
}

 

this ๊ฐ’์€ ๋Ÿฐํƒ€์ž„์— ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋™์ผํ•œ ํ•จ์ˆ˜๋ผ๋„ ๋‹ค๋ฅธ ๊ฐ์ฒด์—์„œ ํ˜ธ์ถœํ–ˆ๋‹ค๋ฉด this๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ’์ด ๋‹ฌ๋ฆฌ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

let user = { name: "John" };
let admin = { name: "Admin" };

function sayHi() {
  alert( this.name );
}

// ๋ณ„๊ฐœ์˜ ๊ฐ์ฒด์—์„œ ๋™์ผํ•œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•จ
user.f = sayHi;
admin.f = sayHi;

// 'this'๋Š” '์ (.) ์•ž์˜' ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ๋•Œ๋ฌธ์—
// this ๊ฐ’์ด ๋‹ฌ๋ผ์ง
user.f(); // John  (this == user)
admin.f(); // Admin  (this == admin)

admin['f'](); // Admin (์ ๊ณผ ๋Œ€๊ด„ํ˜ธ๋Š” ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•จ)

 

๊ฐ์ฒด๊ฐ€ ์—†์–ด๋„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. strict mode๋ผ๋ฉด undefined๊ฐ€ ํ• ๋‹น๋˜๊ณ , strict mode๊ฐ€ ์•„๋‹ ๋•Œ์—๋Š” this๋Š” window๋ผ๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฐ ์‹์˜ ์ฝ”๋“œ๋Š” ๋Œ€๊ฐœ ์‹ค์ˆ˜๋กœ ์ž‘์„ฑ๋œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ํ•จ์ˆ˜ ๋ณธ๋ฌธ์— this๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ๋‹ค๋ฉด, ๊ฐ์ฒด ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

function sayHi() {
  alert(this);
}

sayHi(); // undefined

'use strict';
function sayBye() {
	console.log(this);
}

sayBye();
/**
ref *1> Object [global] {
  global: [Circular *1],
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  queueMicrotask: [Function: queueMicrotask],
  structuredClone: [Function: structuredClone],
  atob: [Getter/Setter],
  btoa: [Getter/Setter],
  performance: [Getter/Setter],
  fetch: [Function: fetch],
  crypto: [Getter]
}
*/

 

this๊ฐ€ ์—†๋Š” ํ™”์‚ดํ‘œ ํ•จ์ˆ˜

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€๋Š” ๋‹ฌ๋ฆฌ ‘๊ณ ์œ ํ•œ’ this๋ฅผ ๊ฐ€์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ this๋ฅผ ์ฐธ์กฐํ•˜๋ฉด, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ‘ํ‰๋ฒ”ํ•œ’ ์™ธ๋ถ€ ํ•จ์ˆ˜์—์„œ this ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ์—์„œ ํ•จ์ˆ˜ arrow()์˜ this๋Š” ์™ธ๋ถ€ ํ•จ์ˆ˜ user.sayHi()์˜ this๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

let user = {
  firstName: "๋ณด๋ผ",
  sayHi() {
    let arrow = () => alert(this.firstName);
    arrow();
  }
};

user.sayHi(); // ๋ณด๋ผ


๋ณ„๊ฐœ์˜ this๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฑด ์›ํ•˜์ง€ ์•Š๊ณ , ์™ธ๋ถ€ ์ปจํ…์ŠคํŠธ์— ์žˆ๋Š” this๋ฅผ ์ด์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ณ„๋„์˜ ์ฑ•ํ„ฐ, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋‹ค์‹œ ์‚ดํŽด๋ณด๊ธฐ์—์„œ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค.


5. new ์—ฐ์‚ฐ์ž์™€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜

์ค‘๊ด„ํ˜ธ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ({...})๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด๋ฅผ.์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ new ํ‚ค์›Œ๋“œ์™€ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋Š”๋ฐ์š”. ๊ทธ ๋ฐฉ๋ฒ•์„ ์•Œ๋ฐ”๋ด…์‹œ๋‹ค.

์ƒ์„ฑ์ž ํ•จ์ˆ˜

"์ผ๋ฐ˜ ํ•จ์ˆ˜"์™€ ๊ตฌ๋ถ„๋˜๋Š” "์ƒ์„ฑ์ž ํ•จ์ˆ˜"๋ผ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์ˆ ์ ์ธ ์ฐจ์ด๋Š” ์—†๊ณ , ๋‘ ๊ด€๋ก€๋ฅผ ๋”ฐ๋ฅผ ๋ฟ์ž…๋‹ˆ๋‹ค.

  1. ํ•จ์ˆ˜์˜ ์ฒซ ๊ธ€์ž๋Š” ๋Œ€๋ฌธ์ž๋กœ.
  2. ๋ฐ˜๋“œ์‹œ "new" ์—ฐ์‚ฐ์ž๋ฅผ ์•ž์— ๋ถ™์—ฌ ์‹คํ–‰

์˜ˆ์‹œ๋ฅผ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

function User(name) {
	this.name = name;
    this.isAdmin = false;
}

let user = new User("๋ณด๋ผ");

alert(user.name); // ๋ณด๋ผ
alert(user.isAdmin); // false

 

new User(...)๋ฅผ ์จ์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์•”์‹œ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

// ์•”์‹œ์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•จ.
function User(name) {
  // this = {};  (๋นˆ ๊ฐ์ฒด๊ฐ€ ์•”์‹œ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ง)

  // ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ this์— ์ถ”๊ฐ€ํ•จ
  this.name = name;
  this.isAdmin = false;

  // return this;  (this๊ฐ€ ์•”์‹œ์ ์œผ๋กœ ๋ฐ˜ํ™˜๋จ)
}

 

1. ๋นˆ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด this์— ํ• ๋‹น

2. ํ•จ์ˆ˜ ๋ณธ๋ฌธ ์‹คํ–‰. (this์— ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด this ์ˆ˜์ •)

3. this return

 

์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ์„ฑ์ด ์—†๋‹ค๋ฉด, ์ต๋ช…ํ•จ์ˆ˜๋กœ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์žฌ์‚ฌ์šฉ์„ ๋ง‰์œผ๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์บก์Šํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = new function() {
  this.name = "John";
  this.isAdmin = false;

  // ์‚ฌ์šฉ์ž ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ ์ฝ”๋“œ.
  // ์ง€์—ญ ๋ณ€์ˆ˜, ๋ณต์žกํ•œ ๋กœ์ง, ๊ตฌ๋ฌธ ๋“ฑ์˜
  // ๋‹ค์–‘ํ•œ ์ฝ”๋“œ๊ฐ€ ์—ฌ๊ธฐ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
};

 

new.target๊ณผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜

new.target ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜๊ฐ€ new์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ์•„๋‹Œ์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • new ํ‚ค์›Œ๋“œ์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋œ ๊ฒฝ์šฐ : ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ return
  • new ํ‚ค์›Œ๋“œ ์—†์ด ํ˜ธ์ถœ๋œ ๊ฒฝ์šฐ : undefined retrurn
function User() {
    console.log(new.target);
}

User(); // undefined

new User(); // [Function: User]

 

new.target์€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ๋ฐ”๋กœ ์ด๋ฅผ ํ™œ์šฉํ•ด new ํ‚ค์›Œ๋“œ ์—†์ด๋„ new ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค. 

function User(name) {
    if(!new.target) {
        return new User(name);
    }

    this.name = name;
}

let userA = User("a");
let userB = new User("b");

console.log(userA.name); // a
console.log(userB.name); // b

 

์ด๋Ÿฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด new๋ฅผ ๋ถ™์—ฌ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋“  ์•„๋‹ˆ๋“  ์ฝ”๋“œ๊ฐ€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ข€ ๋” ์œ ์—ฐํ•˜๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. new๋ฅผ ์ƒ๋žตํ•ด์„œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ผ์ด ์žˆ์„ ์ง€ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ, ๋งŒ์•ฝ ์žˆ๋‹ค๋ฉด ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ฒ ๋„ค์š”.

 

์ƒ์„ฑ์ž์™€ return๋ฌธ

๋ฐ˜ํ™˜ํ•ด์•ผ ํ•  ๊ฒƒ๋“ค์€ ๋ชจ๋‘ this์— ์ €์žฅ๋˜๊ณ , this๋Š” ์ž๋™์œผ๋กœ ๋ฐ˜ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜ํ™˜๋ฌธ์„ ๋ช…์‹œ์ ์œผ๋กœ ์จ ์ค„ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒ์„ฑ์žํ•จ์ˆ˜์—” ๋ณดํ†ต return ๋ฌธ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ return ๋ฌธ์ด ์žˆ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ์š”?

  • return ์›์‹œํ˜• : ๋ฌด์‹œ๋จ
  • return ๊ฐ์ฒด : this ๋Œ€์‹  ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋จ.
function BigUser() {
  this.name = "์›์ˆญ์ด";
  return { name: "๊ณ ๋ฆด๋ผ" };  // <-- this๊ฐ€ ์•„๋‹Œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•จ
}

alert( new BigUser().name );  // ๊ณ ๋ฆด๋ผ


function SmallUser() {
  this.name = "์›์ˆญ์ด";
  return; // <-- this๋ฅผ ๋ฐ˜ํ™˜ํ•จ
}

alert( new SmallUser().name );  // ์›์ˆญ์ด

 

์ƒ์„ฑ์ž ๋‚ด ๋ฉ”์†Œ๋“œ

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•ด ๊ฐ์ฒด ๋‚ด๋ถ€๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—„์ฒญ๋‚œ ์œ ์—ฐ์„ฑ์ด ํ™•๋ณด๋˜์ฃ .
์ง€๊ธˆ๊นŒ์ง„ this์— ํ”„๋กœํผํ‹ฐ๋ฅผ ๋”ํ•ด์ฃผ๋Š” ์˜ˆ์‹œ๋งŒ ์‚ดํŽด๋ดค๋Š”๋ฐ, ๋ฉ”์†Œ๋“œ๋ฅผ ๋”ํ•ด์ฃผ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜ ์˜ˆ์‹œ์—์„œ new User(name)๋Š” ํ”„๋กœํผํ‹ฐ name๊ณผ ๋ฉ”์„œ๋“œ sayHi๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

function User(name) {
  this.name = name;

  this.sayHi = function() {
    alert( "์ œ ์ด๋ฆ„์€ " + this.name + "์ž…๋‹ˆ๋‹ค." );
  };
}

let bora = new User("์ด๋ณด๋ผ");

bora.sayHi(); // ์ œ ์ด๋ฆ„์€ ์ด๋ณด๋ผ์ž…๋‹ˆ๋‹ค.

/*
bora = {
   name: "์ด๋ณด๋ผ",
   sayHi: function() { ... }
}
*/

6. ์˜ต์…”๋„ ์ฒด์ด๋‹ '?.'

์˜ต์…”๋„ ์ฒด์ด๋‹ "?."์„ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ๊ฐ€ "์—†๋Š”" ์ค‘์ฒฉ ๊ฐ์ฒด๋ฅผ ์—๋Ÿฌ์—†์ด ์•ˆ์ „ํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

์˜ˆ์ „ JS์—์„œ๋Š” ์ฒด์ด๋‹๋œ ๊ฐ์ฒด์˜ ํŠน์ • ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•ญ์ƒ AND๋กœ ์—ฐ๊ฒฐํ•ด์„œ ์‹ค์ œ ํ•ด๋‹น ๊ฐ์ฒด๋‚˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š”์ง€ ๋จผ์ € ํ™•์ธ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

// ์˜ˆ์‹œ
alert( obj && obj.obj2 && obj.obj2.obj3 && obj.obj2.obj3.property )

 

์ด๋ ‡๊ฒŒ AND๋กœ ์—ฐ๊ฒฐํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง„๋‹ค๋Š” ๋‹จ์ ์„ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ์˜ต์…”๋„ ์ฒด์ด๋‹ "?."์ž…๋‹ˆ๋‹ค.

?.์€ ?.'์•ž’์˜ ํ‰๊ฐ€ ๋Œ€์ƒ์ด undefined๋‚˜ null์ด๋ฉด ํ‰๊ฐ€๋ฅผ ๋ฉˆ์ถ”๊ณ  undefined๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ๋ฐ˜๋“œ์‹œ '์•ž'์˜ ํ‰๊ฐ€ ๋Œ€์ƒ์€ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‰ฝ๊ฒŒ๋งํ•ด,  '์•ž'์˜ ํ‰๊ฐ€ ๋Œ€์ƒ์€ ๋ณ€์ˆ˜๋กœ์„œ ์„ ์–ธ ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๋‚จ)

let user = { 
	name : {
        containsA : false,
    }
};

undefined?.name // undefined 
null?.name // undefined
user?.name // kim
user.name?.containsA // false

// user๊ฐ€ null ๋˜๋Š” undefined๊ฐ€ ์•„๋‹ˆ๊ณ  ์‹ค์ œ ๊ฐ’์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š”
// ๋ฐ˜๋“œ์‹œ user.address ํ”„๋กœํผํ‹ฐ๋Š” ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
// ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด user?.address.street์˜ ๋‘ ๋ฒˆ์งธ ์  ์—ฐ์‚ฐ์ž์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ
// ์ด๋ฅผ ํ™œ์šฉํ•œ๋‹ค๋ฉด ?.๋กœ ๊ณ„์† ์—ฐ๊ฒฐํ•ด์„œ ์ค‘์ฒฉ ํ”„๋กœํผํ‹ฐ๋“ค์— ์•ˆ์ „ํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ.
user?.address.street // error : address prop is not exist.

 

์ด ์™ธ์—๋„ "?."๋Š” ๋˜ ๋‹ค๋ฅธ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ ?.[prop], ?.method() ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • obj?.prop – obj๊ฐ€ ์กด์žฌํ•˜๋ฉด obj.prop์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด undefined๋ฅผ ๋ฐ˜ํ™˜ํ•จ.
  • obj?.[prop] – obj๊ฐ€ ์กด์žฌํ•˜๋ฉด obj[prop]์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด undefined๋ฅผ ๋ฐ˜ํ™˜ํ•จ.
  • obj?.method() – obj๊ฐ€ ์กด์žฌํ•˜๋ฉด obj.method()๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด undefined๋ฅผ ๋ฐ˜ํ™˜ํ•จ.

7. Symbol

JS๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ์˜ค์ง ๋ฌธ์žํ˜•๊ณผ ์‹ฌ๋ณผํ˜•๋งŒ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. 

let obj = {};
obj[true] // error
obj[undefined] // error
obj[1] // error
obj[null] // error

์ง€๊ธˆ๊นŒ์ง€๋Š” ํ”„๋กœํผํ‹ฐ ํ‚ค๊ฐ€ ๋ฌธ์žํ˜•์ธ ๊ฒฝ์šฐ๋งŒ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ์‹ฌ๋ณผ๊ฐ’์„ ์‚ฌ์šฉํ•ด๋ณด๋ฉด์„œ ์ด์ ์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์‹ฌ๋ณผ์€ "์œ ์ผ ์‹๋ณ„์ž"๋ฅผ ๋งŒ๋“ค๊ณ ์ž ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์‹ฌ๋ณผ๊ฐ’์€ Symbol()์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let k = Symbol("k");

์‹ฌ๋ณผ์€ ์œ ์ผ์„ฑ์„ ๋ณด์žฅํ•˜๋Š” "์ž๋ฃŒํ˜•"์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์ด ๋™์ผํ•œ ์‹ฌ๋ณผ์ด๋ผ๊ณ  ํ•ด์„œ ๊ฐ ์‹ฌ๋ณผ์ด ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

let id1 = Symbol("id");
let id2 = Symbol("id");

console.log(id1 == id2); // false

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ๋ฌธ์žํ˜•์œผ๋กœ์˜ ์•”์‹œ์  ํ˜• ๋ณ€ํ™˜์ด ๋น„๊ต์  ์ž์œ ๋กญ๊ฒŒ ์ผ์–ด๋‚˜๋Š” ํŽธ์ž…๋‹ˆ๋‹ค. alert ํ•จ์ˆ˜๊ฐ€ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฐ’์„ ์ธ์ž๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์ด์œ ๊ฐ€ ์ด ๋•Œ๋ฌธ์ด์ฃ . ๊ทธ๋Ÿฌ๋‚˜ ์‹ฌ๋ณผ์€ ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค. ์‹ฌ๋ณผํ˜• ๊ฐ’์€ ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•์œผ๋กœ ์•”์‹œ์  ํ˜• ๋ณ€ํ™˜(์ž๋™ ํ˜• ๋ณ€ํ™˜)๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ์—์„œ alert๋Š” ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

let id = Symbol("id");
console.log(id); // error
  • ๋ณด์‹œ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ฌธ์ž์—ด๊ณผ ์‹ฌ๋ณผ์€ ๊ทผ๋ณธ๋ถ€ํ„ฐ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋กœ์˜ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋ฐ˜๋“œ์‹œ ์ถœ๋ ฅํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด .toString() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ์‹ฌ๋ณผ์˜ .description ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค.

'์ˆจ๊น€' ํ”„๋กœํผํ‹ฐ

์‹ฌ๋ณผ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ˆจ๊น€ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€ ์ฝ”๋“œ์—์„œ ์ ‘๊ทผ ๋ฐ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด์ฃ . ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค.

let user = { 
	name: "John"
};

let id = Symbol("id");

user[id] = 1;

alert( user[id] ); // ์‹ฌ๋ณผ์„ ํ‚ค๋กœ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

user ๊ฐ์ฒด๊ฐ€ ์„œ๋“œํŒŒํ‹ฐ๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์™€ ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด๋ผ ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.

์ด ๋•Œ ์‹ฌ๋ณผ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์„œ๋“œํŒŒํ‹ฐ ์ฝ”๋“œ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋“œํŒŒํ‹ฐ ์ฝ”๋“œ๊ฐ€ ๋ชจ๋ฅด๊ฒŒ user์— ์‹๋ณ„์ž๋ฅผ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ฌ๋ณผ์€ ์œ ์ผ์„ฑ์ด ๋ณด์žฅ๋˜๋ฏ€๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์‹๋ณ„์ž์™€ ์ œ3์˜ ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋งŒ๋“  ์‹๋ณ„์ž๊ฐ€ ์ถฉ๋Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„์ด ๊ฐ™๋”๋ผ๋„ ๋ง์ด์ฃ .

let user = { name: "John" };

// ๋ฌธ์ž์—ด "id"๋ฅผ ์‚ฌ์šฉํ•ด ์‹๋ณ„์ž๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
user.id = "์Šคํฌ๋ฆฝํŠธ id ๊ฐ’";

// ๋งŒ์•ฝ ์ œ3์˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์šฐ๋ฆฌ ์Šคํฌ๋ฆฝํŠธ์™€ ๋™์ผํ•˜๊ฒŒ ๋ฌธ์ž์—ด "id"๋ฅผ ์ด์šฉํ•ด ์‹๋ณ„์ž๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด...

user.id = "์ œ3 ์Šคํฌ๋ฆฝํŠธ id ๊ฐ’"
// ์˜๋„์น˜ ์•Š๊ฒŒ ๊ฐ’์ด ๋ฎ์–ด ์“ฐ์—ฌ์„œ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์‹๋ณ„์ž๋Š” ๋ฌด์˜๋ฏธํ•ด์ง‘๋‹ˆ๋‹ค.


๋งŒ์•ฝ ์‹ฌ๋ณผ ๋Œ€์‹  ๋ฌธ์ž์—ด "id"๋ฅผ ์‚ฌ์šฉํ•ด ์‹๋ณ„์ž๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด ๊ธฐ์กด ๊ฐ’๊ณผ์˜ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์‹ฌ๋ณผ์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์‹ฌ๋ณผ์€ for in์—์„œ๋„ ๋ฐฐ์ œ๋˜์–ด ์‹ฌ๋ณผ ๊ทธ ์ž์ฒด๋กœ ์ˆจ๊น€ ํ”„๋กœํผํ‹ฐ์˜ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Object.keys(user)์—์„œ๋„ ํ‚ค๊ฐ€ ์‹ฌ๋ณผ์ธ ํ”„๋กœํผํ‹ฐ๋Š” ๋ฐฐ์ œ๋ฉ๋‹ˆ๋‹ค. '์‹ฌ๋ณผํ˜• ํ”„๋กœํผํ‹ฐ ์ˆจ๊ธฐ๊ธฐ(hiding symbolic property)'๋ผ ๋ถˆ๋ฆฌ๋Š” ์ด๋Ÿฐ ์›์น™ ๋•๋ถ„์— ์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์‹ฌ๋ณผํ˜• ํ‚ค๋ฅผ ๊ฐ€์ง„ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

 

But, Object.assgin์€ ํ‚ค๊ฐ€ ์‹ฌ๋ณผ์ธ ํ”„๋กœํผํ‹ฐ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.

let id = Symbol("id");
let user = {
  [id]: 123
};

let clone = Object.assign({}, user);

alert( clone[id] ); // 123

 

์ถ”๊ฐ€๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋‚œ ํ›„์— ์‹ฌ๋ณผ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋ณด๋‹ค, ๊ฐ์ฒด ์ƒ์„ฑ ๊ณผ์ •์—์„œ ์‹ฌ๋ณผ์„ ํ”„๋กœํผํ‹ฐ๋กœ ๋„ฃ๊ณ  ์‹ถ๋‹ค๋ฉด [] ๋Œ€๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

let id = Symbol("id");

let user = {
  name: "John",
  [id]: 123 // "id": 123์€ ์•ˆ๋จ
};

 

Symbol.for() - ์ „์—ญ ์‹ฌ๋ณผ ์ƒ์„ฑ

// ์ „์—ญ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ์‹ฌ๋ณผ์„ ์ฝ์Šต๋‹ˆ๋‹ค.
let id = Symbol.for("id"); // ๋งŒ์•ฝ "id"์ด๋ฆ„์˜ ์‹ฌ๋ณผ์ด ์ „์—ญ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ƒˆ๋กœ์šด ์‹ฌ๋ณผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

// ๋™์ผํ•œ ์ด๋ฆ„์„ ์ด์šฉํ•ด ์‹ฌ๋ณผ์„ ๋‹ค์‹œ ์ฝ์Šต๋‹ˆ๋‹ค(์ข€ ๋” ๋ฉ€๋ฆฌ ๋–จ์–ด์ง„ ์ฝ”๋“œ์—์„œ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค).
let idAgain = Symbol.for("id");

// ๋‘ ์‹ฌ๋ณผ์€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
alert( id === idAgain ); // true

 

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์‹ฌ๋ณผ์ด๋ผ๋ฉด ์ „์—ญ ์‹ฌ๋ณผ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

Symbol.keyFor() - ์ „์—ญ ์‹ฌ๋ณผ์˜ ์ด๋ฆ„ get

Symbol.for๊ณผ ๋ฐ˜๋Œ€๋กœ ์‹ฌ๋ณผ์„ ์ด์šฉํ•ด ์‹ฌ๋ณผ์˜ ์ด๋ฆ„์„ getํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ฐ”๋กœ keyFor()์ž…๋‹ˆ๋‹ค.

// ์ด๋ฆ„์„ ์ด์šฉํ•ด ์‹ฌ๋ณผ์„ ์ฐพ์Œ
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");

// ์‹ฌ๋ณผ์„ ์ด์šฉํ•ด ์ด๋ฆ„์„ ์–ป์Œ
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id

 

์ „์—ญ ์‹ฌ๋ณผ์ด ์•„๋‹Œ ๋ชจ๋“  ์‹ฌ๋ณผ์€ description ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ „์—ญ์‹ฌ๋ณผ์ด ์•„๋‹Œ ์ผ๋ฐ˜ ์‹ฌ๋ณผ์—์„œ ์ด๋ฆ„์„ ์–ป๊ณ  ์‹ถ์œผ๋ฉด description ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

let localSymbol = Symbol("name");
alert( localSymbol.description ); // name

 

์‹œ์Šคํ…œ ์‹ฌ๋ณผ

'์‹œ์Šคํ…œ ์‹ฌ๋ณผ(system symbol)'์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์‹ฌ๋ณผ์ž…๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ ์‹ฌ๋ณผ์„ ํ™œ์šฉํ•˜๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฏธ์„ธ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator, Symbol.toPrimitive ๊ธฐํƒ€ ๋“ฑ๋“ฑ

8.  ๊ฐ์ฒด๋ฅผ ์›์‹œํ˜•์œผ๋กœ ๋ณ€ํ™˜

JS์—์„œ๋Š” ๊ฐ์ฒด๋ฅผ ํ˜•๋ณ€ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ "hint"๋ผ๊ณ  ํ•˜๋Š” ๊ธฐ์ค€ ๊ฐ’์— ์˜ํ•ด ํ˜•๋ณ€ํ™˜์ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ์ฒด๋ฅผ console๋กœ ์ถœ๋ ฅํ•˜๋ ค ํ•œ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š”์ด "hint"์— ์˜ํ•ด ์ž๋™์œผ๋กœ string์œผ๋กœ ํ˜•๋ณ€ํ™˜์ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. hint์˜ ์ข…๋ฅ˜์—๋Š” string, number, default ์ด 3๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ด…์‹œ๋‹ค.

 

string

let user = { 
    name : 'kim'
};

console.log(user); // string์œผ๋กœ ํ˜•๋ณ€ํ™˜

 

console.log ๋ฉ”์†Œ๋“œ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์˜ค๋Š” ๊ฐ์ฒด๋“ค์„ string์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ฝ˜์†”์— ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ์›์‹œํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •์—์„œ "hint"๊ฐ€ string์ด ๋ฉ๋‹ˆ๋‹ค.

 

number

๊ฐ์ฒด๊ฐ„ ์—ฐ์‚ฐ์„ ์‹œ๋„ํ•˜๋Š” ๊ฒฝ์šฐ ๊ฐ์ฒด์˜ hint๋Š” number๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

const people = {
    age: 24,
    name: 'James'
}

const now = Date.now();
const someday = new Date('2024-09-27');

const num = +people; // ๊ฐ์ฒด -> ์ˆซ์žํ˜• ๋ณ€ํ™˜
const day = now - someday; // ๋‘ ๋‚ ์งœ๊ฐ„์˜ ์ฐจ์ด

console.log(num, day); // NaN, 93788797

 

default

์—ฐ์‚ฐ์ž๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ์ž๋ฃŒํ˜•์ด ํ™•์‹คํ•˜์ง€ ์•Š์„ ๋•Œ๋Š” 'hint'๊ฐ€ default ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ดํ•ญ ๋ง์…ˆ ์—ฐ์‚ฐ์ž + ๋Š” ํ”ผ์—ฐ์‚ฐ์ž์˜ ์ž๋ฃŒํ˜•์— ๋”ฐ๋ผ "๋ฌธ์ž์—ด์„ ํ•ฉ์น˜๋Š” ์—ฐ์‚ฐ"์„ ํ•  ์ˆ˜๋„, "์ˆซ์ž๋ฅผ ๋”ํ•ด์ฃผ๋Š” ์—ฐ์‚ฐ"์„ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ +์˜ ์ธ์ˆ˜๊ฐ€ "๊ฐ์ฒด"์ผ ๋–„๋Š” hint๊ฐ€ default๊ฐ€ ๋ฉ๋‚Ÿ.

 

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋™๋“ฑ์—ฐ์‚ฐ์ž == ๋˜ํ•œ ๊ฐ์ฒด-๋ฌธ์žํ˜•, ๊ฐ์ฒด-์ˆซ์žํ˜•, ๊ฐ์ฒด-์‹ฌ๋ณผํ˜•๋ผ๋ฆฌ ๋น„๊ตํ•  ๋•Œ๋„ ๊ฐ์ฒด๋ฅผ ์–ด๋–ค ์ž๋ฃŒํ˜•์œผ๋กœ ๋ฐ”๊ฟ”์•ผ ํ•  ์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ hint ๊ฐ€ default ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

// ์ดํ•ญ ๋ง์…ˆ ์—ฐ์‚ฐ์€ hint๋กœ `default`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
let total = obj1 + obj2;

// obj == number ์—ฐ์‚ฐ์€ hint๋กœ `default`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
if (user == 1) { ... };

"boolean" hint๋Š” ์—†์Šต๋‹ˆ๋‹ค.
hint๋Š” ์ด ์„ธ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์•„์ฃผ ๊ฐ„๋‹จํ•˜์ฃ .‘boolean’ hint๋Š” ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋ชจ๋“  ๊ฐ์ฒด๋Š” ๊ทธ๋ƒฅ true๋กœ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค.

 

 

Symbol.toPrimitive

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—” Symbol.toPrimitive๋ผ๋Š” ๋‚ด์žฅ ์‹ฌ๋ณผ์ด ์กด์žฌํ•˜๋Š”๋ฐ, ์ด ์‹ฌ๋ณผ์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ์ž๋ฃŒํ˜•(hint)์„ ๋‚ด ์ž…๋ง›๋Œ€๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

let user = {
    name : 'John',
    money : 10000,
    
    [Symbol.toPrimitive](hint) {
        console.log(`hint: ${hint}`);
        return hint == "string" ? `{name: "${this.name}"}` : this.money;
    }
}

console.log(user); // hint ๊ฐ€ string์ด๋ฏ€๋กœ return {name: ${this.name}} 
console.log(+user); // hint ๊ฐ€ string์ด ์•„๋‹ˆ๋ฏ€๋กœ return this.money
console.log(user + 500); // hint ๊ฐ€ string์ด ์•„๋‹ˆ๋ฏ€๋กœ return this.money

์ด๋ ‡๊ฒŒ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด ๋†“์œผ๋ฉด user๋Š” hint์— ๋”ฐ๋ผ (์ž๊ธฐ ์ž์‹ ์„ ์„ค๋ช…ํ•ด์ฃผ๋Š”) ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋˜๊ธฐ๋„ ํ•˜๊ณ  (๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ˆ์˜ ์•ก์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š”) ์ˆซ์ž๋กœ ๋ณ€ํ™˜๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. user[Symbol.toPrimitive]๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋กœ ๋ชจ๋“  ์ข…๋ฅ˜์˜ ํ˜• ๋ณ€ํ™˜์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

toString(), valueOf()

Symbol.toPrimitive์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ํ˜•๋ณ€ํ™˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ toString()๊ณผ valueOf()๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ง์ด์ฃ .

๊ฐ์ฒด-์›์‹œํ˜• ๋ณ€ํ™˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์˜ํ•ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

๊ฐ์ฒด์— Symbol.toPrimitive๊ฐ€ ์—†์œผ๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์•„๋ž˜ ๊ทœ์น™์— ๋”ฐ๋ผ toString์ด๋‚˜ valueOf๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  • hint๊ฐ€ 'string’์ธ ๊ฒฝ์šฐ: toString -> valueOf ์ˆœ(toString์ด ์žˆ๋‹ค๋ฉด toString์„ ํ˜ธ์ถœ, toString์ด ์—†๋‹ค๋ฉด valueOf๋ฅผ ํ˜ธ์ถœํ•จ)
  • ๊ทธ ์™ธ(number, default) : valueOf -> toString ์ˆœ ํ˜ธ์ถœ 

๋”ฐ๋ผ์„œ ์ด hint๊ฐ€ string์ธ ๊ฒฝ์šฐ์—๋Š” toString(), number๋‚˜ default์ธ ๊ฒฝ์šฐ์—๋Š” valueOf() ๋ฉ”์†Œ๋“œ์— ์–ด๋–ป๊ฒŒ ์›์‹œํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ• ์ง€ ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•์„ ์ž‘์„ฑํ•˜๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

let user = {
  name: "John",
  money: 1000,

  // hint๊ฐ€ "string"์ธ ๊ฒฝ์šฐ
  toString() {
    return `{name: "${this.name}"}`;
  },

  // hint๊ฐ€ "number"๋‚˜ "default"์ธ ๊ฒฝ์šฐ
  valueOf() {
    return this.money;
  }

};

alert(user); // toString -> {name: "John"}
alert(+user); // valueOf -> 1000
alert(user + 500); // valueOf -> 1500

 

๊ฐ„ํ˜น ๋ชจ๋“  ํ˜• ๋ณ€ํ™˜์„ ํ•œ ๊ณณ์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ (hint๊ฐ€ number๋˜ string์ด๋˜ default๋˜ ์ƒ๊ด€์—†์ด ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ) ์—๋Š” toString()๋งŒ ๊ตฌํ˜„ํ•ด์ฃผ๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

(Symbol.toPrimitive์™€ valueOf๊ฐ€ ๋ชจ๋‘ ์—†์œผ๋ฉด toString์ด ๋ชจ๋“  ํ˜•๋ณ€ํ™˜์„ ์ฑ…์ž„์ง€๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .)

let user = {
  name: "John",

  toString() {
    return this.name;
  }
};

alert(user); // toString -> John
alert(user + 500); // toString -> John500

 

๋ฒˆ์™ธ : ์ถ”๊ฐ€ ํ˜•๋ณ€ํ™˜

์œ„์™€ ๊ฐ™์ด toString()๋งŒ ์ž‘์„ฑํ•œ ๊ฒฝ์šฐ ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ฐ๊ฐ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ์š”?

let obj = {
  toString() {
    return "2";
  }
};

alert(obj + 2); // (1)

let obj = {
  toString() {
    return "2";
  }
};

alert(obj * 2); // (2)

 

(1) : toString()์€ ๊ธฐ๋ณธ์ ์œผ๋กœ hint๊ฐ€ 'string'์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฌธ์ž์—ด ๋ณ‘ํ•ฉ์„ ์šฐ์„ ์ˆœ์œ„๋กœ ๋‘๊ฒ ์ฃ . ๊ฒฐ๊ณผ๋Š” 22์ž…๋‹ˆ๋‹ค.

(2) : toString()์— ์˜ํ•ด obj๊ฐ€ ๋ฌธ์ž์—ด "2"๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ด "2" * 2๊ฐ€ ๋˜๊ณ  ์ด๊ฒƒ์€ ๋‹ค์‹œ 2 * 2๋กœ ๋ณ€ํ™˜๋˜์–ด ๊ฒฐ๊ณผ๋Š” 4๊ฐ€ ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์‚ฌ์‹ค obj.toString()๋งŒ ์‚ฌ์šฉํ•ด๋„ '๋ชจ๋“  ๋ณ€ํ™˜’์„ ๋‹ค ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค๋ฌด์—์„  obj.toString()๋งŒ ๊ตฌํ˜„ํ•ด๋„ ์ถฉ๋ถ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ Symbol.toPrimitive๋กœ๋„ ๊ฐ hint๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ . valueOf()๋กœ number, default๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•ฉ์‹œ๋‹ค.


9. ํ”„๋กœํผํ‹ฐ Flag์™€ ์„ค๋ช…์ž

์ง€๊ธˆ๊นŒ์ง€๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๋‹จ์ˆœํžˆ key-value ๊ด€์ ์—์„œ๋งŒ ๋‹ค๋ค˜์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ๊ฐ๋ณด๋‹ค ๋” ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๊ตฌ์กฐ์ธ๋ฐ์š”.

์ด๋ฒˆ์—๋Š” ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€ ๊ตฌ์„ฑ ์˜ต์…˜ ๋ช‡ ๊ฐ€์ง€๋ฅผ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

ํ”„๋กœํผํ‹ฐ Flag

  • writable : true ๋ฉด ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. false์ธ ๊ฒฝ์šฐ ์ฝ๊ธฐ(get)๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • enumerable : true ๋ฉด ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•ด ๋‚˜์—ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. false์ธ ๊ฒฝ์šฐ ๋ฐ˜๋ณต๋ฌธ์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • configurable : true ๋ฉด ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ๋‚˜ ํ”Œ๋ž˜๊ทธ ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. false์ธ ๊ฒฝ์šฐ ์‚ญ์ œ, ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  flag๋Š” default๋กœ true๋กœ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ”„๋กœํผํ‹ฐ์˜ flag ์ •๋ณด๋Š” Object.getOwnPropertyDescriptor๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ชจ๋‘ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
let user = {
  name: "John"
};

let descriptor = Object.getOwnPropertyDescriptor(user, 'name');

alert( JSON.stringify(descriptor, null, 2 ) );
/* property descriptor:
{
  "value": "John",
  "writable": true,
  "enumerable": true,
  "configurable": true
}
*/

 

๋ฉ”์„œ๋“œ Object.defineProperty๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”Œ๋ž˜๊ทธ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = {
  name: "John"
};

Object.defineProperty(user, "name", {
  writable: false
});

 

Object.defineProperties(obj, descriptors) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ํ•œ ๋ฒˆ์— ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Object.defineProperties(user, {
  name: { value: "John", writable: false },
  surname: { value: "Smith", writable: false },
  // ...
});

 

Object.getOwnPropertyDescriptors(obj) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœํผํ‹ฐ ์„ค๋ช…์ž๋ฅผ ์ „๋ถ€ ํ•œ๊บผ๋ฒˆ์— ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฉ”์„œ๋“œ๋ฅผ Object.defineProperties์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด ๋ณต์‚ฌ ์‹œ ํ”Œ๋ž˜๊ทธ๋„ ํ•จ๊ป˜ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ( for๋ฌธ์„ ํ†ตํ•ด ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ํ•œ๋‹ค๊ณ  ํ•ด์„œ ํ”„๋กœํผํ‹ฐ์˜ ํ”Œ๋ž˜๊ทธ๊นŒ์ง€ ๋ณต์‚ฌ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. )

let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));

 

์ด ์™ธ์—๋„ ๊ฐ์ฒด ์ˆ˜์ •์„ ๋ง‰์•„์ฃผ๋Š” ๋‹ค์–‘ํ•œ ๋ฉ”์†Œ๋“œ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž˜ ์‚ฌ์šฉ๋˜์ง„ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ๊ฒŒ ์žˆ๊ตฌ๋‚˜ ์ •๋„๋กœ ๋ณด๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

  • Object.preventExtensions(obj)
    • ๊ฐ์ฒด์— ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • Object.seal(obj)
    • ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€๋‚˜ ๊ธฐ์กด ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ๋ฅผ ๋ง‰์•„์ค๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ ์ „์ฒด์— configurable: false๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ํšจ๊ณผ์ž…๋‹ˆ๋‹ค.
  • Object.freeze(obj)
    • ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€๋‚˜ ๊ธฐ์กด ํ”„๋กœํผํ‹ฐ ์‚ญ์ œ, ์ˆ˜์ •์„ ๋ง‰์•„์ค๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ ์ „์ฒด์— configurable: false, writable: false๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ํšจ๊ณผ์ž…๋‹ˆ๋‹ค.

์•„๋ž˜ ๋ฉ”์„œ๋“œ๋Š” ์œ„ ์„ธ ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„ค์ •ํ•œ ์ œ์•ฝ์‚ฌํ•ญ์„ ํ™•์ธํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Object.isExtensible(obj)
    • ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ false๋ฅผ, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • Object.isSealed(obj)
    • ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€, ์‚ญ์ œ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ  ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๊ฐ€ configurable: false์ด๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • Object.isFrozen(obj)
    • ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€, ์‚ญ์ œ, ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ  ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๊ฐ€ configurable: false, writable: false์ด๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

10. Getter & Setter

๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋Š” ํฌ๊ฒŒ ๋‘ ์ข…๋ฅ˜๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ : ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ•œ key-value ์Œ์˜ ๋ฐ์ดํ„ฐ. ์ด ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ flag๋ฅผ ์œ„์—์„œ ๋‹ค๋ฃจ์—ˆ์Œ.
  • ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ : getter์™€ setter.

JS์—์„œ Getter์™€ Setter๋Š” get๊ณผ set์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = {
    name : 'kim',
    get name() {
        ...
    },

    set name(value) {
        ...
    }
};

getter ๋ฉ”์†Œ๋“œ๋Š” user.name์„ ์‚ฌ์šฉํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์œผ๋ ค๊ณ  ํ•  ๋•Œ ์‹คํ–‰๋˜๊ณ , setter ๋ฉ”์†Œ๋“œ๋Š” user.name = value๋กœ ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋ ค ํ•  ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

console.log(user.name); //  name Getter ์‹คํ–‰
user.name = 'park'; // name Setter ์‹คํ–‰

 

๊ทธ๋ ‡๋‹ค๋ฉด get๊ณผ set์€ ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด์„œ๋งŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์ฒ˜๋Ÿผ getter์™€ setter ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๊ฐ์ฒด์—” fullName์ด๋ผ๋Š” '๊ฐ€์ƒ’์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. ๊ฐ€์ƒ์˜ ํ”„๋กœํผํ‹ฐ๋Š” ์ฝ๊ณ  ์“ธ ์ˆœ ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

let user = {
  name: "John",
  surname: "Smith",

  get fullName() {
    return `${this.name} ${this.surname}`;
  }
};

alert(user.fullName); // John Smith
user.fullName = "Test"; // Error (ํ”„๋กœํผํ‹ฐ์— getter ๋ฉ”์„œ๋“œ๋งŒ ์žˆ์–ด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.)

 

Getter & Setter ์„ค๋ช…์ž

์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์ธ getter, setter์—๋„ ํ”„๋กœํผํ‹ฐ flag๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ flag์˜ value์™€ writable์ด ์—†๋Š” ๋Œ€์‹  get๊ณผ set์ด๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

  • get – ์ธ์ˆ˜๊ฐ€ ์—†๋Š” ํ•จ์ˆ˜๋กœ, ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ์„ ๋•Œ ๋™์ž‘ํ•จ
  • set – ์ธ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ธ ํ•จ์ˆ˜๋กœ, ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ์“ธ ๋•Œ ํ˜ธ์ถœ๋จ
  • enumerable – ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์™€ ๋™์ผํ•จ
  • configurable – ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ์™€ ๋™์ผ

๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์ด defineProperty์— ์„ค๋ช…์ž get๊ณผ set์„ ์ „๋‹ฌํ•˜๋ฉด fullName์„ ์œ„ํ•œ ์ ‘๊ทผ์ž๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = {
  name: "John",
  surname: "Smith"
};

Object.defineProperty(user, 'fullName', {
  get() {
    return `${this.name} ${this.surname}`;
  },

  set(value) {
    [this.name, this.surname] = value.split(" ");
  }
});

alert(user.fullName); // John Smith

for(let key in user) alert(key); // name, surname

 

์ฃผ์˜ํ•  ์ ์œผ๋กœ๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ(get/set ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง)๋‚˜ ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ(value๋ฅผ ๊ฐ€์ง) ์ค‘ ํ•œ ์ข…๋ฅ˜์—๋งŒ ์†ํ•˜๊ณ  ๋‘˜ ๋‹ค์— ์†ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์ ์„ ํ•ญ์ƒ ์œ ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ํ•œ ํ”„๋กœํผํ‹ฐ์— get๊ณผ value๋ฅผ ๋™์‹œ์— ์„ค์ •ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

// Error: Invalid property descriptor.
Object.defineProperty({}, 'prop', {
  get() {
    return 1
  },

  value: 2
});

 

getter, setter ํ™œ์šฉํ•˜๊ธฐ

getter, setter๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ ์›ํ•˜๋Š”๋Œ€๋กœ ํ†ต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let user = {
  get name() {
    return this._name;
  },

  set name(value) {
    if (value.length < 4) {
      alert("์ž…๋ ฅํ•˜์‹  ๊ฐ’์ด ๋„ˆ๋ฌด ์งง์Šต๋‹ˆ๋‹ค. ๋„ค ๊ธ€์ž ์ด์ƒ์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”.");
      return;
    }
    this._name = value;
  }
};

user.name = "Pete";
alert(user.name); // Pete

user.name = ""; // ๋„ˆ๋ฌด ์งง์€ ์ด๋ฆ„์„ ํ• ๋‹นํ•˜๋ ค ํ•จ

 

user์˜ ์ด๋ฆ„์€ _name์— ์ €์žฅ๋˜๊ณ , ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์€ getter์™€ setter๋ฅผ ํ†ตํ•ด ์ด๋ค„์ง‘๋‹ˆ๋‹ค.

๊ธฐ์ˆ ์ ์œผ๋ก  ์™ธ๋ถ€ ์ฝ”๋“œ์—์„œ user._name์„ ์‚ฌ์šฉํ•ด ์ด๋ฆ„์— ๋ฐ”๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

์ด ๋•Œ ๋ฐ‘์ค„ "_" ๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒด ๋‚ด๋ถ€์—์„œ๋งŒ ํ™œ์šฉํ•˜๊ณ , ์™ธ๋ถ€์—์„œ๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š” ๊ฒƒ(getterํ•œ๋‹ค๊ฑฐ๋‚˜ setterํ•˜์ง€ ์•Š๋Š” ๊ฒƒ)์ด ๊ด€์Šต์ž…๋‹ˆ๋‹ค.

 

์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ํ™œ์šฉํ•˜์—ฌ OCP ์ง€ํ‚ค๊ธฐ

๋งŒ์•ฝ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ธฐ์กด ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•  ๋•Œ,

function User(name, age) {
  this.name = name;
  this.age = age;
}

let john = new User("John", 25);

alert( john.age ); // 25

 

age ํ”„๋กœํผํ‹ฐ ๋Œ€์‹  birthday ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค๋Š” ์š”๊ตฌ์‚ฌํ•ญ์˜ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚ฌ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.

age ํ”„๋กœํผํ‹ฐ๋Š” ์‚ญ์ œํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค๊ณ  ํ•  ๋•Œ, ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ์ข‹์„๊นŒ์š”?

 

์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ๊ทธ ์ •๋‹ต์ž…๋‹ˆ๋‹ค.

function User(name, birthday) {
    this.name = name;
    this.birthday = birthday;

    Object.defineProperty(this, 'age', {
        get() {
            let nowYear = new Date().getFullYear();
            return nowYear - this.birthday.getFullYear();
        },
    });
}

let john = new User('John', new Date(1992, 6, 1));

console.log(john.age);
console.log(john.birthday);

 

์ด์ œ ๊ธฐ์กด ์ฝ”๋“œ๋„ ์ž˜ ์ž‘๋™ํ•˜๊ณ , ํ”„๋กœํผํ‹ฐ๋„ ์ƒ๊ฒผ๋„ค์š”. ์ด๋ ‡๊ฒŒ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ํ™•์žฅํ•˜์—ฌ OCP๋ฅผ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.


์ด๋ ‡๊ฒŒ JS์˜ Object์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ OOP ์–ธ์–ด์™€ ๋น„์Šทํ•œ ์ ๋„ ๋งŽ๊ณ , ์ƒˆ๋กœ์šด ์ ๋„ ๋งŽ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.


ํŠนํžˆ ๊ฐ๊ฐ์˜ ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด Object.defineProperty()๋ฅผ ํ†ตํ•ด getter์™€ setter๋ฅผ ์ œ์–ดํ•œ๋‹ค๋Š” ์ ์ด ์บก์Šํ™” ์ธก๋ฉด์—์„œ Java์™€๋Š” ๋ฐฉ์‹์ด ๋‹ฌ๋ผ ํฅ๋ฏธ๋กœ์› ์Šต๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ ‘๊ทผ ๋ฐฉ์‹์€ ๋ณด๋‹ค ์œ ์—ฐํ•˜๊ณ  ์„ธ๋ฐ€ํ•œ ์ œ์–ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜์ง€๋งŒ, ์ž๋ฐ”์˜ ์บก์Šํ™”๋Š” private, protected, public ๊ฐ™์€ ์ ‘๊ทผ ์ œ์–ด์ž๋ฅผ ์‚ฌ์šฉํ•ด ํด๋ž˜์Šค ๋‚ด ๋ฉค๋ฒ„(ํ•„๋“œ, ๋ฉ”์„œ๋“œ ๋“ฑ)์˜ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ œ์–ดํ•˜์—ฌ ์•ˆ์ •์ ์ด๊ณ  ์—„๊ฒฉํ•œ ๋ฐ์ดํ„ฐ ๋ณดํ˜ธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ด์–ด ๊ฐ์ฒด์™€ ๊ด€๋ จ ๊นŠ์€ JS์˜ ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ