๐Ÿ“– ํ”„๋กœํ† ํƒ€์ž…

c_yjยท2022๋…„ 6์›” 27์ผ
0

DeepDive

๋ชฉ๋ก ๋ณด๊ธฐ
16/42
post-thumbnail

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ช…๋ นํ˜•, ํ•จ์ˆ˜ํ˜•, ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง€์›ํ•˜๋Š” ๋ฉ€ํ‹ฐ ํŒจ๋Ÿฌ๋‹ค์ž„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ด๋‹ค.
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ฐ์ฒด ๊ธฐ๋ฐ˜์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ด๋ฉฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด๋ฃจ๊ณ  ์žˆ๋Š” ๊ฑฐ์˜ "๋ชจ๋“  ๊ฒƒ"์ด ๊ฐ์ฒด๋‹ค.

โœ”๏ธ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋…๋ฆฝ์  ๋‹จ์œ„, ์ฆ‰ ๊ฐ์ฒด์˜ ์ง‘ํ•จ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์„ ํ‘œํ˜„ํ•˜๋ ค๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„์„ ๋งํ•œ๋‹ค.

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์‹ค์„ธ๊ณ„์˜ ์‹ค์ฒด๋ฅผ ์ธ์‹ํ•˜๋Š” ์ฒ ํ•™์  ์‚ฌ๊ณ ๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์ ‘๋ชฉํ•˜๋ ค๋Š” ์‹œ๋„์—์„œ ์‹œ์ž‘ํ•œ๋‹ค. ์‹ค์ฒด๋Š” ํŠน์ง•์ด๋‚˜ ์„ฑ์งˆ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ด๋ฅผ ํ†ตํ•ด ์‹ค์ฒด๋ฅผ ์ธ์‹ํ•˜๊ฑฐ๋‚˜ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์–‘ํ•œ ์†์„ฑ ์ค‘์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ํ•„์š”ํ•œ ์†์„ฑ๋งŒ ๊ฐ„์ถ”๋ ค ๋‚ด์–ด ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ƒํ™”๋ผ ํ•œ๋‹ค.

โœ”๏ธ ์ƒ์†๊ณผ ํ”„๋กœํ† ํƒ€์ž…

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

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Circle(radius){
  this.radius = radius;
  this.getArea = function () {
    //Math.PI๋Š” ์›์ฃผ์œจ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ƒ์ˆ˜๋‹ค.
    return Math.PI * this.radius ** 2;
  };
}

//๋ฐ˜์ง€๋ฆ„์ด 1์ธ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
const circle1 = new Circle(1);
//๋ฐ˜์ง€๋ฆ„์ด 2์ธ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
const circle2 = new Circle(2);

// Circle ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋–„๋งˆ๋‹ค ๋™์ผํ•œ ๋™์ž‘์„ ํ•˜๋Š”
// getArea ๋ฉ”์„œ๋“œ๋ฅผ ์ค‘๋ณต ์ƒ์„ฑํ•˜๊ณ  ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ์ค‘๋ณต ์†Œ์œ ํ•œ๋‹ค.
// getArea ๋ฉ”์„œ๋“œ๋Š” ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•˜์—ฌ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณต์œ ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•œ๋‹ค.
console.log(circle1.getArea === circle2.getArea); // false

console.log(circle1.getArea()); // 3.1415926
console.log(circle2.getArea()); // 12.56637

์ƒ์†์„ ํ†ตํ•ด ๋ถˆํ•„์š”ํ•œ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•ด ๋ณด์ž. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ”„๋กœํ† ํƒ€์ž…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์†์„ ๊ตฌํ˜„ํ•œ๋‹ค.

function Circle(radius){
  this.radius= radius;
}

// Circle ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ getArea ๋ฉ”์„œ๋“œ๋ฅผ
// ๊ณต์œ ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ”„๋กœํ† ํƒ€์ž…์— ์ถ”๊ฐ€ํ•œ๋‹ค.
// ํ”„๋กœํ† ํƒ€์ž…์€ Circle ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ์— ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ๋‹ค.
Circle.prototype.getArea = function() {
  return Math.PI * this.radius ** 2;
};

// ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
const circle1 = new Circle(1);
const circle2 = new Circle(2);

// Circle ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋Š” ๋ถ€๋ชจ ๊ฐ์ฒด์˜ ์—ญํ• ์„ ํ•˜๋Š”
// ํ”„๋กœํ† ํƒ€์ž… Circle.prototype์œผ๋กœ๋ถ€ํ„ฐ getArea ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค.
// ์ฆ‰, Circle ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋Š” ํ•˜๋‚˜์˜ getArea ๋ฉ”์„œ๋“œ๋ฅผ ๊ณต์œ ํ•œ๋‹ค.
console.log(circle1.getArea === circle2.getArea); // true

console.log(circle1.getArea()); // 3.14159265
console.log(circle2.getArea()); // 12.5663

โœ”๏ธ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด

ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๋ž€ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ทผ๊ฐ„์„ ์ด๋ฃจ๋Š” ๊ฐ์ฒด ๊ฐ„ ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.
ํ”„๋กœํ† ํƒ€์ž…์€ ์–ด๋–ค ๊ฐ์ฒด์˜ ์ƒ์œ„ ๊ฐ์ฒด์˜ ์—ญํ• ์„ ํ•˜๋Š” ๊ฐ์ฒด๋กœ์„œ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๊ณต์œ  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ํ”„๋กœํ† ํƒ€์ž…์„ ์ƒ์†๋ฐ›์€ ํ•˜์œ„ ๊ฐ์ฒด๋Š” ์ƒ์œ„ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ž์‹ ์˜ ํ”„๋กœํผํ‹ฐ์ฒ˜๋Ÿผ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
๋ชจ๋“  ๊ฐ์ฒด๋Š” [[Prototype]] ์ด๋ผ๋Š” ๋‚ด๋ถ€ ์Šฌ๋กฏ์„ ๊ฐ€์ง€๋ฉฐ, ์ด ๋‚ด๋ถ€ ์Šฌ๋กฏ์˜ ๊ฐ’์€ ํ”„๋กœํ† ํƒ€์ž…์˜ ์ฐธ์กฐ๋‹ค. [[Prototype]]์— ์ €์žฅ๋˜๋Š” ํ”„๋กœํ† ํƒ€์ž…์€ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹์— ์˜ํ•ด ๊ฒฐ์ •๋œ๋‹ค. ์ฆ‰, ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋–„ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹์— ๋”ฐ๋ผ ํ”„๋กœํ† ํƒ€์ž…์ด ๊ฒฐ์ •๋˜๊ณ  [[Prototype]]์— ์ €์žฅ๋œ๋‹ค.

๋ชจ๋“  ๊ฐ์ฒด๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ–๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ํ”„๋กœํ† ํƒ€์ž…์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค. ์ฆ‰, ๊ฐ์ฒด์™€ ํ”„๋กœํ† ํƒ€์ž…๊ณผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค.

โœ”๏ธ __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ

๋ชจ๋“  ๊ฐ์ฒด๋Š” __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ์ž์‹ ์˜ ํ”„๋กœํ† ํƒ€์ž…, ์ฆ‰ [[Prototype]] ๋‚ด๋ถ€ ์Šฌ๋กฏ์— ๊ฐ„์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

const person = {name: 'Lee'};

โœ๏ธ __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋‹ค

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์›์น™์ ์œผ๋กœ ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ์— ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตX ๋‹จ, ์ผ๋ถ€ ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ์— ํ•œํ•˜์—ฌ ๊ฐ„์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์„ ์ œ๊ณตํ•˜๊ธฐ๋Š” ํ•œ๋‹ค.

โœ๏ธ __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์†์„ ํ†ตํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

__proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒด๊ฐ€ ์ง์ ‘ ์†Œ์œ ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๋ผ Object.prototype์˜ ํ”„๋กœํผํ‹ฐ๋‹ค. ๋ชจ๋“  ๊ฐ์ฒด๋Š” ์ƒ์†์„ ํ†ตํ•ด Object.prototype.__proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ๏ธ __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ํ”„๋กœํ† ํƒ€์ž…์— ์ ‘๊ทผํ•˜๋Š” ์ด์œ 

[[Prototype]] ๋‚ด๋ถ€ ์Šฌ๋กฏ์˜ ๊ฐ’, ์ฆ‰ ํ”„๋กœํ† ํƒ€์ž…์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ์ƒํ˜ธ ์ฐธ์กฐ์— ์˜ํ•ด ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์ด ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์œผ๋ฅด ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋‹ค.

const parent = {};
const child = {};
// child์˜ ํ”„๋กœํ† ํƒ€์ž…์„ parent๋กœ ์„ค์ •
child.__proto__ = parent;
// parent์˜ ํ”„๋กœํ† ํƒ€์ž…์„ child๋กœ ์„ค์ •
parent.__proto__ = child; // TypeError: Cyclic __proto__ value


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

โœ๏ธ __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฝ”๋“œ ๋‚ด์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

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

๋”ฐ๋ผ์„œ ํ”„๋กœํผํ‹ฐ ๋Œ€์‹  ํ”„๋กœํ† ํƒ€์ž…์˜ ์ฐธ์กฐ๋ฅผ ์ทจ๋“ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์—๋Š” Object.getPrototpyeOf ๋ฉ”์„œ๋“œ๋‚˜ Object.setPrototypeOf ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.

const obj = {};
const parent = { x: 1 };

// obj ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ์ทจ๋“
Object.getPrototypeOf(obj); // obj.__proto__;
// obj ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ต์ฒด
Object.setPrototypeOf(obj, parent); // obj.__proto__ = parent;

console.log(obj.x); // 1

โœ”๏ธ ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ prototype ํ”„๋กœํผํ‹ฐ

ํ•จ์ˆ˜ ๊ฐ์ฒด๋งŒ์ด ์†Œ์œ ํ•˜๋Š” prototype ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

// ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ์†Œ์œ ํ•œ๋‹ค.
(function () {}).hasOwnProperty('prototype'); // true

// ์ผ๋ฐ˜ ๊ฐ์ฒด๋Š” prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ์†Œ์œ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
({}).hasOwnProperty('prototype'); // false

prototype ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋Š” ํ•จ์ˆ˜, ์ฆ‰ non-constructor์ธ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์™€ ES6 ๋ฉ”์„œ๋“œ ์ถ•์•ฝ ํ‘œํ˜„์œผ๋กœ ์ •์˜ํ•œ ๋ฉ”์„œ๋“œ๋Š” prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ์†Œ์œ ํ•˜์ง€ ์•Š์œผ๋ฉฐ ํ”„๋กœํ† ํƒ€์ž…๋„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”(์—„๋ฐ€ํžˆ ๋งํ•˜๋ฉด Object.prototype์œผ๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์€) __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ์™€ ํ•จ์ˆ˜ ๊ฐ์ฒด๋งŒ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” prototype ํ”„๋กœํผํ‹ฐ๋Š” ๊ฒฐ๊ตญ ๋™์ผํ•œ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

๊ตฌ๋ถ„์†Œ์œ ๊ฐ’์‚ฌ์šฉ ์ฃผ์ฒด์‚ฌ์šฉ ๋ชฉ์ 
__proto__๋ชจ๋“  ๊ฐ์ฒดํ”„๋กœํ† ํƒ€์ž…์˜ ์ฐธ์กฐ๋ชจ๋“  ๊ฐ์ฒด๊ฐ์ฒด๊ฐ€ ์ž์‹ ์˜ ํ”„๋กœํ† ํƒ€์ž…์— ์ ‘๊ทธ ๋˜๋Š” ๊ต์ฒดํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
prototype ํ”„๋กœํผํ‹ฐconstructorํ”„๋กœํ† ํƒ€์ž…์˜ ์ฐธ์กฐ์ƒ์„ฑ์ž ํ•จ์ˆ˜์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ž์‹ ์ด ์ƒ์„ฑํ•  ๊ฐœ์ฒด(์ธ์Šคํ„ด์Šค)์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ํ• ๋‹นํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

โœ”๏ธ ํ”„๋กœํ† ํƒ€์ž…์˜ constructor ํ”„๋กœํผํ‹ฐ์™€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜

๋ชจ๋“  ํ”„๋กœํ† ํƒ€์ž…์€ constructor ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š”๋‹ค. ์ด constructor ํ”„๋กœํผํ‹ดใ„ด prototype ํ”„๋กœํผํ‹ฐ๋กœ ์ž์‹ ์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ์ด ์—ฐ๊ฒฐ์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ค๋  ๋–„, ์ฆ‰ ํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์ด๋ค„์ง„๋‹ค.

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Person(name) {
  this.name = name;
}

const me = new Person('Lee');
// me ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” Person์ด๋‹ค.
console.log(me.constructor === Person); // true

โœ”๏ธ ๋ฆฌํ„ฐ๋Ÿด ํ‘œ๊ธฐ๋ฒ•์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ํ”„๋กœํ† ํƒ€์ž…

์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋Š” ํ”„๋กœํ† ํƒ€์ž…์˜ constructor ํ”„๋กœํผํ‹ฐ์— ์˜ํ•ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ์—ฐ๊ฒฐ๋œ๋‹ค.

// obj ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ํ•จ์ˆ˜๋Š” Object์ด๋‹ค.
const obj = new Object();
console.log(obj.constructor === Object); // true

// add ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” Function์ด๋‹ค.
const add = new Function('a','b','return a + b');
console.log(add.constructor === Function); //true

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Person(name) {
  this.name = name;
}

// me ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” Person์ด๋‹ค.
const me = new Person('Lee');
console.log(me.constructor === Person); // true

๋ฆฌํ„ฐ๋Ÿด ํ‘œ๊ธฐ๋ฒ•์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹๊ณผ ๊ฐ™์ด ๋ช…์‹œ์ ์œผ๋กœ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹๋„ ์žˆ๋‹ค.

// ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด
const obj = {};

// ํ•จ์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด
const add = function (a,b) { return a+b;;
                            
// ๋ฐฐ์—ด ๋ฆฌํ„ฐ๋Ÿด
const arr = [1,2,3];

// ์ •๊ทœ ํ‘œํ˜„์‹ ๋ฆฌํ„ฐ๋Ÿด
const regexp = /is/ig;      

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

ํ”„๋กœํ† ํƒ€์ž…๊ณผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ๋‹จ๋…์œผ๋กœ ์กด์žฌํ•  ์ˆ˜ ์—†๊ณ  ์–ธ์ œ๋‚˜ ์Œ์œผ๋กœ ์กด์žฌํ•œ๋‹ค.

โœ”๏ธ ํ”„๋กœํ† ํƒ€์ž…์˜ ์ƒ์„ฑ ์‹œ์ 

ํ”„๋กœํ† ํƒ€์ž…์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์‹œ์ ์— ๋”๋ถˆ์–ด ์ƒ์„ฑ๋œ๋‹ค/
ํ”„๋กœํ† ํƒ€์ž…๊ณผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ๋‹จ๋…์œผ๋กœ ์กด์žฌํ•  ์ˆ˜ ์—†๊ณ  ์–ธ์ œ๋‚˜ ์Œ์œผ๋กœ ์กด์žฌํ•˜๊ธฐ ๋–„๋ฌธ์ด๋‹ค.

โ˜‘๏ธ ์‚ฌ์šฉ์ž ์ •์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ํ”„๋กœํ† ํƒ€์ž… ์ƒ์„ฑ ์‹œ์ 

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜, ์ฆ‰ constructor๋Š” ํ•จ์ˆ˜ ์ •์˜๊ฐ€ ํ‰๊ฐ€๋˜์–ด ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์‹œ์ ์— ํ”„๋กœํ† ํƒ€์ž…๋„ ๋”๋ถˆ์–ด ์ƒ์„ฑ๋œ๋‹ค.

// ํ•จ์ˆ˜ ์ •์˜(constructor)๊ฐ€ ํ‰๊ฐ€๋˜์–ด ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์‹œ์ ์— ํ”„๋กœํ† ํƒ€์ž…๋„ ๋”๋ถˆ์–ด ์ƒ์„ฑ๋œ๋‹ค.
console.log(Person.prototype); // {constructor: f}

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Person(name) {
  this.name = name;
}

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋Š” ํ•จ์ˆ˜, ์ฆ‰ non-constructor๋Š” ํ”„๋กœํ† ํƒ€์ž…์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.

// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” non-constructor๋‹ค.
const Person = name => {
  this.name = name;
};

// non-constructor๋Š” ํ”„๋กœํ† ํƒ€์ž…์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.
console.log(Person.prototype); // undefined

์ƒ์„ฑ๋œ ํ”„๋กœํ† ํƒ€์ž…์€ ์˜ค์ง constructor ํ”„๋กœํผํ‹ฐ๋งŒ์„ ๊ฐ–๋Š” ๊ฐ์ฒด๋‹ค.

ํ”„๋กœํ† ํƒ€์ž…๋„ ๊ฐ์ฒด์ด๊ณ  ๋ชจ๋“  ๊ฐ์ฒด๋Š” ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ€์ง€๋ฏ€๋กœ ํ”„๋กœํ† ํƒ€์ž…๋„ ์ž์‹ ์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ–๋Š”๋‹ค.
์ƒ์„ฑ๋œ ํ”„๋กœํ† ํƒ€์ž…์˜ ํ”„๋กœํ† ํƒ€์ž…์€ Object.prototype์ด๋‹ค.

โ˜‘๏ธ ๋นŒํŠธ์ธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ํ”„๋กœํ† ํƒ€์ž… ์ƒ์„ฑ ์‹œ์ 

Object, String, Number, Function, Array, RegExp, Date, Promise ๋“ฑ๊ณผ ๊ฐ™์€ ๋นŒํŠธ์ธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋„ ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋นŒํŠธ์ธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์‹œ์ ์— ํ”„๋กœํ† ํƒ€์ž…์ด ์ƒ์„ฑ๋œ๋‹ค.

๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ์ด์ „์— ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ํ”„๋กœํ† ํƒ€์ž…์€ ์ด๋ฏธ ๊ฐ์ฒดํ™” ๋˜์–ด ์กด์žฌํ•œ๋‹ค.์ดํ›„ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋˜๋Š” ๋ฆฌํ„ฐ๋Ÿด ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ํ”„๋กœํ† ํƒ€์ž…์€ ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ [[Prototype]] ๋‚ด๋ถ€ ์Šฌ๋กฏ์— ํ• ๋‹น๋œ๋‹ค.

โœ”๏ธ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹๊ณผ ํ”„๋กœํ† ํƒ€์ž…์˜ ๊ฒฐ์ •

๊ฐ์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค์–‘ํ•œ ์ƒ์„ฑ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

  • ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด
  • Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜
  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜
  • Object.create ๋ฉ”์„œ๋“œ
  • ํด๋ž˜์Šค(ES6)

โ˜‘๏ธ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ํ‰๊ฐ€ํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ถ”์ƒ ์—ฐ์‚ฐ OrdinaryObjectCreate๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค ์ด๋•Œ ์ถ”์ƒ ์—ฐ์‚ฐ OrdinaryObjectCreae์— ์ „๋‹ฌ๋˜๋Š” ํ”„๋กœํ† ํƒ€์ž…์€ Object.prototype์ด๋‹ค. ์ฆ‰, ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์€ Object.prototype์ด๋‹ค.

const obj = { x: 1 };

โ˜‘๏ธ Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…

Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜ ์—†์ด ํ˜ธ์ถœํ•˜๋ฉด ๋นˆ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค. Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ถ”์ƒ ์—ฐ์‚ฐ OrdinaryObjectCreate๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ์ด๋•Œ ์ถ”์ƒ ์—ฐ์‚ฐ OrdinaryObjectCreae์— ์ „๋‹ฌ๋˜๋Š” ํ”„๋กœํ† ํƒ€์ž…์€ Object.prototype์ด๋‹ค. ์ฆ‰ Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์€ Object.prototype์ด๋‹ค.

const obj = new Object();
obj.x = 1;


Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ obj ๊ฐ์ฒด๋Š” Object.prototype์„ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ–๊ฒŒ ๋˜๋ฉฐ, ์ด๋กœ์จ Object.prototype์„ ์ƒ์†๋ฐ›๋Š”๋‹ค.

const obj = new Object();
obj.x = 1;

// Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ Obj ๊ฐ์ฒด๋Š” Object.prototype๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค.
console.log(obj.constructor === Object); // true
console.log(obj.hasOwnProperty('x') // true

๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ object ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹์˜ ์ฐจ์ด๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์— ์žˆ๋‹ค. ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ๋ฐฉ์‹์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ๋‚ด๋ถ€์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€๋งŒ Object ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋ฐฉ์‹์€ ์ผ๋‹จ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ์ดํ›„ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

โ˜‘๏ธ ์ƒ์„ฑ์ž ํ• ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…

new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ถ”์ƒ ์—ฐ์‚ฐ OrdinaryObjectCreate๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ์ด๋–„ ์ถ”์ƒ ์—ฐ์‚ฐ OrdinaryObjectCreate์— ์ „๋‹ฌ๋˜๋Š” ํ”„๋กœํ† ํƒ€์ž…์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ์— ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ๋Š” ๊ฐ์ฒด๋‹ค. ์ฆ‰, ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ์— ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ๋Š” ๊ฐ์ฒด๋‹ค.

function Person(name){
  this.name = name;
}

const me = new Person('Lee');

โœ”๏ธ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ

function Person(name) {
  this.name = name;
}

// ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ
Person.prototype.sayHello = function () {
  console.log(`Hi! My name is ${this.name}`);
};

const me = new Person('Lee');

// hasOwnProperty๋Š” Object.prototype์˜ ๋ฉ”์„œ๋“œ๋‹ค.
console.log(me.hasOwnProperty('name')); // true

Person ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ me ๊ฐ์ฒด๋Š” Object.prototype์˜ ๋ฉ”์„œ๋“œ์ธ hasOwnProperty๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ me ๊ฐ์ฒด๊ฐ€ Person.prototype๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Object.prtotype๋„ ์ƒ์†๋ฐ›์•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

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

ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์˜ ์ตœ์ƒ์œ„์— ์œ„์น˜ํ•˜๋Š” ๊ฐ์ฒด๋Š” ์–ธ์ œ๋‚˜ Object.prototype์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ๊ฐ์ฒด๋Š” Object.prototype์„ ์ƒ์†๋ฐ›๋Š”๋‹ค. Object.prototype์„ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์˜ ์ข…์ ์ด๋ผ ํ•œ๋‹ค.

ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์€ ์ƒ์†๊ณผ ํ”„๋กœํผํ‹ฐ ๊ฒ€์ƒ‰์„ ์œ„ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜
์Šค์ฝ”ํ”„ ์ฒด์ธ์€ ์‹๋ณ„์ž ๊ฒ€์ƒ‰์„ ์œ„ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜

โœ”๏ธ ์˜ค๋ฒ„๋ผ์ด๋”ฉ๊ณผ ํ”„๋กœํผํ‹ฐ ์„€๋„์ž‰

const Person = (function () {
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜
  function Person(name) {
    this.name = name;
  }
  // ํ”„๋กœํ† ํƒ€์ž„ ๋ฉ”์„œ๋“œ
  Person.prototype.sayHello = function () {
    console.log(`Hi! My name is ${this.name}`);
  };
  
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
  return Person;
}());

const me = new Person('Lee');

// ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ
me.sayHello = function () {
  console.log(`Hey : My name is ${this.name}`);
};

// ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ๋Š” ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ์— ์˜ํ•ด ๊ฐ€๋ ค์ง„๋‹ค.
me.sayHello(); // Hey! My name is Lee

ํ”„๋กœํ† ํƒ€์ž…์ด ์†Œ์œ ํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ”„๋กœํ† ํƒ€์ž… ํ”„๋กœํผํ‹ฐ, ์ธ์Šคํ„ด์Šค๊ฐ€ ์†Œ์œ ํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ธ์Šคํ„ด์Šค ํ”„๋กœํผํ‹ฐ๋ผ๊ณ  ํ•œ๋‹ค.
ํ”„๋กœํ† ํƒ€์ž… ํ”„๋กœํผํ‹ฐ์™€ ๊ฐ™์€ ์ด๋ฆ„์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ธ์Šคํ„ด์Šค์— ์ถ”๊ฐ€ํ•˜๋ฉด ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ๋”ฐ๋ผ ํ”„๋กœํ† ํƒ€์ž… ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ํ”„๋กœํ† ํƒ€์ž… ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฎ์–ด์“ฐ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ธ์Šคํ„ด์Šค ํ”„๋กœํผํ‹ฐ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด๋•Œ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ sayHello๋Š” ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ sayHello๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ–ˆ๊ณ  ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ sayHello๋Š” ๊ฐ€๋ ค์ง„๋‹ค. ์ด์ฒ˜๋Ÿผ ์ƒ์† ๊ด€๊ณ„์— ์˜ํ•ด ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐ€๋ ค์ง€๋Š” ํ˜„์ƒ์„ ํ”„๋กœํผํ‹ฐ ์„€๋„์ž‰์ด๋ผ ํ•œ๋‹ค.

โœ๏ธ์˜ค๋ฒ„๋ผ์ด๋”ฉ
์ƒ์œ„ ํด๋ž˜์Šค๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ์žฌ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค

โœ๏ธ์˜ค๋ฒ„๋กœ๋”ฉ
ํ•จ์ˆ˜์˜ ์ด๋ฆ„์€ ๋™์ผํ•˜์ง€๋งŒ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž… ๋˜๋Š” ๊ฐœ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ๋งค๊ฐœ๋ณ€์ˆ˜์— ์˜ํ•ด ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌ๋ณ„ํ•˜์—ฌ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์˜ค๋ฒ„๋กœ๋”ฉ์„ ์ง€์›ํ•˜์ง€ ์•Š์ง€๋งŒ arguments ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜๋Š” ์žˆ๋‹ค.

ํ•˜์œ„ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ํ”„๋กœํ† ํƒ€์ž…์— get ์•ก์„ธ์Šค๋Š” ํ—ˆ์šฉ๋˜๋‚˜ set ์•ก์„ธ๋А๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

โœ”๏ธ ํ”„๋กœํ† ํƒ€์ž…์˜ ๊ต์ฒด

ํ”„๋กœํ† ํƒ€์ž…์€ ์ž„์˜์˜ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถ€๋ชจ ๊ฐ์ฒด์ธ ํ”„๋กœํ† ํƒ€์ž…์„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์ง•์„ ํ™œ์šฉํ•˜์—ฌ ๊ฐ์ฒด ๊ฐ„์˜ ์ƒ์† ๊ด€๊ณ„๋ฅผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. ํ”„๋กœํ†  ํƒ€์ž…์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋˜๋Š” ์ธ์Šคํ„ด์Šค์— ์˜ํ•ด ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.

โ˜‘๏ธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•œ ํ”„๋กœํ† ํƒ€์ž…์˜ ๊ต์ฒด

const Person = (function () {
 function Person(name) {
   this.name = name;
 }

 //  โ‘  ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ํ”„๋กœํ† ํƒ€์ž…์„ ๊ต์ฒด
 Person.prototype = {
   sayHello() {
     console.log(`Hi! My name is ${this.name}`);
   }
 };

 return Person;
}());

const me = new Person('Lee');

โ‘ ์—์„œ Person.prototype์— ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ํ• ๋‹นํ–ˆ๋Š”๋ฐ,
์ด๋Š” Person ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๋กœ ๊ต์ฒดํ•œ ๊ฒƒ์ด๋‹ค.

ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ๊ต์ฒดํ•œ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์—๋Š” constructor ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๋‹ค. constructor ํ”„๋กœํผํ‹ฐ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์ด ํ”„๋กœํ† ํƒ€์ž…์„ ์ƒ์„ฑํ•  ๋–„ ์•”๋ฌต์ ์œผ๋กœ ์ถ”๊ฐ€ํ•œ ํ”„๋กœํผํ‹ฐ๋‹ค. ๋”ฐ๋ผ์„œ me ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด Person์ด ์•„๋‹Œ Object๊ฐ€ ๋‚˜์˜จ๋‹ค.

ํ”„๋กœํ† ํƒ€์ž…์„ ๊ต์ฒดํ•˜๋ฉด constructor ํ”„๋กœํผํ‹ฐ์™€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๊ฐ„์˜ ์—ฐ๊ฒฐ์ด ํŒŒ๊ดด๋˜๋Š”๋ฐ ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ๊ต์ฒดํ•œ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— constructor ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ”„๋กœํ† ํƒ€์ž…์˜ constructor ํ”„๋กœํผํ‹ฐ๋ฅผ ๋˜์‚ด๋ฆฐ๋‹ค.

โ˜‘๏ธ ์ธ์Šคํ„ด์Šค์— ์˜ํ•œ ํ”„๋กœํ† ํƒ€์ž…์˜ ๊ต์ฒด

ํ”„๋กœํ† ํƒ€์ž…์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ธ์Šคํ„ด์Šค์˜ __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํฌํ‹ฐ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ธ์Šคํ„ด์Šค์˜ __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ํ”„๋กœํ† ํƒ€์ž…์„ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.
์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ์— ๋‹ค๋ฅธ ์ž„์˜์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ฒƒ์€ ๋ฏธ๋ž˜์— ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

function Person(name) {
  this.name = name;
}

const me = new Person("april");

// ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ๊ต์ฒดํ•  ๊ฐ์ฒด
const parent = {
  // constructor ํ”„๋กœํผํ‹ฐ์™€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๊ฐ„์˜ ์—ฐ๊ฒฐ์„ ์„ค์ •
  constructor: Person,
  sayHello() {
    console.log(`Hi! My name is ${this.name}`);
  },
};

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ์™€ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ„์˜ ์—ฐ๊ฒฐ์„ ์„ค์ •
Person.prototype = parent;

// โ‘  me ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ parent ๊ฐ์ฒด๋กœ ๊ต์ฒดํ•œ๋‹ค.
Object.setPrototypeOf(me, parent);
// ์œ„ ์ฝ”๋“œ๋Š” ์•„๋ž˜์˜ ์ฝ”๋“œ์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
// me.__proto__ = parent;

me.sayHello(); // Hi! My name is april

โ‘ ์—์„œ me ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ parent ๊ฐ์ฒด๋กœ ๊ต์ฒดํ–ˆ๋‹ค.

// constructor ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
console.log(me.constructor === Person); // true
console.log(me.constructor === Object); // false

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ต์ฒด๋œ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
console.log(Person.prototype === Object.getPrototypeOf(me)); // true

function Person(name) {
  this.name = name;
}

const me = new Person('Lee');

// ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ๊ต์ฒดํ•  ๊ฐ์ฒด
const parent = {
  // constructor ํ”„๋กœํผํ‹ฐ์™€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๊ฐ„์˜ ์—ฐ๊ฒฐ์„ ์„ค์ •
  constructor : Person,
  sayHello() {
    console.log(`Hi! My name is ${this.name}`);
  }
};

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ์™€ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ„์˜ ์—ฐ๊ฒฐ์„ ์„ค์ •
Person.prototype = parent;

// me ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์„ parent ๊ฐ์ฒด๋กœ ๊ต์ฒดํ•œ๋‹ค.
Object.setPrototypeOf(me, parent);
// ์œ„ ์ฝ”๋“œ๋Š”  ์•„๋ž˜์˜ ์ฝ”๋“œ์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค
// me.__proto__ = parent;

me.sayHello(); // Hi! My name is Lee

// constructor ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
console.log(me.constructor === Person); // true
console.log(me.constructor === Object); // false

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ต์ฒด๋œ ํ”„๋กœํ† ํƒ€์ž…์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
console.log(Person.prototype === Object.getPrototypeOf(me)); // true

ํ”„๋กœํ† ํƒ€์ž…์€ ์ง์ ‘ ๊ต์ฒดํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

โœ”๏ธ instanceof ์—ฐ์‚ฐ์ž

๊ฐ์ฒด instanceof ์ƒ์„ฑ์ž ํ•จ์ˆ˜

์šฐ๋ณ€์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype์— ๋ฐ”์ธ๋”ฉ๋œ ๊ฐ์ฒด๊ฐ€ ์ขŒ๋ณ€์˜ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ƒ์— ์กด์žฌํ•˜๋ฉด true๋กœ ํ‰๊ฐ€๋˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” false๋กœ ํ‰๊ฐ€๋œ๋‹ค.

instanceof ์—ฐ์‚ฐ์ž๋Š” ํ”„๋กœํ† ํƒ€์ž…์˜ constructor ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜
prototype์— ๋ฐ”์ธ๋”ฉ๋œ ๊ฐ์ฒด๊ฐ€ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ƒ์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

โœ”๏ธ ์ง์ ‘ ์ƒ์†

โ˜‘๏ธ Object.create์— ์˜ํ•œ ์ง์ ‘ ์ƒ์†

Object.create ๋ฉ”์„œ๋“œ๋Š” ๋ช…์‹œ์ ์œผ๋กœ ํ”„๋กœํ† ํƒ€์ž…์„ ์ง€์ •ํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ. Object.create ๋ฉ”์„œ๋“œ๋„ ๋‹ค๋ฅธ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ถ”์ƒ ์—ฐ์‚ฐ OrdinaryObjectCreate๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
Object.create ๋ฉ”์„œ๋“œ์˜ ์ฒซ ๋ฒˆ์จฐ ๋งค๊ฐœ๋ณ€์ˆ˜์—๋Š” ์ƒ์„ฑํ•  ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ์ง€์ •ํ•  ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์—๋Š” ์ƒ์„ฑํ•  ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ํ‚ค์™€ ํ”„๋กœํผํ‹ฐ ํ”„๋กœํผํ‹ฐ ๋””์Šคํฌ๋ฆฝํ„ฐ ๊ฐ์ฒด๋กœ ์ด๋ค„์ง„ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. ์ด ๊ฐ์ฒด์˜ ํ˜•์‹์€ Object.defineProperties ๋ฉ”์„œ๋“œ์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜์™€ ๋™์ผํ•˜๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์˜ต์…˜์ด๋ฏ€๋กœ ์ƒ๋žต ๊ฐ€๋Šฅ

 // ํ”„๋กœํ† ํƒ€์ž…์ด null์ธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋Š” ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์˜ ์ข…์ ์— ์œ„์น˜ํ•œ๋‹ค.
// obj โ†’ null
let obj = Object.create(null);
console.log(Object.getPrototypeOf(obj) === null); // true
// Object.prototype์„ ์ƒ์†๋ฐ›์ง€ ๋ชปํ•œ๋‹ค.
console.log(obj.toString()); // TypeError: obj.toString is not a function

// obj โ†’ Object.prototype โ†’ null
// obj = {};์™€ ๋™์ผํ•˜๋‹ค.
obj = Object.create(Object.prototype);
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true

// obj โ†’ Object.prototype โ†’ null
// obj = { x: 1 };์™€ ๋™์ผํ•˜๋‹ค.
obj = Object.create(Object.prototype, {
  x: { value: 1, writable: true, enumerable: true, configurable: true }
});
// ์œ„ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๋™์ผํ•˜๋‹ค.
// obj = Object.create(Object.prototype);
// obj.x = 1;
console.log(obj.x); // 1
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true

const myProto = { x: 10 };
// ์ž„์˜์˜ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์†๋ฐ›๋Š”๋‹ค.
// obj โ†’ myProto โ†’ Object.prototype โ†’ null
obj = Object.create(myProto);
console.log(obj.x); // 10
console.log(Object.getPrototypeOf(obj) === myProto); // true

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Person(name) {
  this.name = name;
}

// obj โ†’ Person.prototype โ†’ Object.prototype โ†’ null
// obj = new Person('Lee')์™€ ๋™์ผํ•˜๋‹ค.
obj = Object.create(Person.prototype);
obj.name = 'Lee';
console.log(obj.name); // Lee
console.log(Object.getPrototypeOf(obj) === Person.prototype); // true

Object.create ๋ฉ”์„œ๋“œ๋Š” ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ „๋‹ฌ๋œ ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์— ์†ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ฆ‰, ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ ์ง์ ‘์ ์œผ๋กœ ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด ๋ฉ”์„œ๋“œ์˜ ์žฅ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • new ์—ฐ์‚ฐ์ž๊ฐ€ ์—†์ด๋„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ”„๋กœํ† ํƒ€์ž…์„ ์ง€์ •ํ•˜๋ฉด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋„ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

โ˜‘๏ธ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ๋‚ด๋ถ€์—์„œ __proto__์— ์˜ํ•œ ์ง์ ‘ ์ƒ์†

Es6์—์„œ๋Š” ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ๋‚ด๋ถ€์—์„œ __proto__ ์ ‘๊ทผ์ž ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ ‘ ์ƒ์†์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

const myProto = { x: 10 };

// ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ์˜ํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ ํ”„๋กœํ† ํƒ€์ž…์„ ์ง€์ •ํ•˜์—ฌ ์ง์ ‘ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
const obj = {
  y: 20,
  // ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์†๋ฐ›๋Š”๋‹ค.
  // obj โ†’ myProto โ†’ Object.prototype โ†’ null
  __proto__: myProto
};

/** ์œ„ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๋™์ผํ•˜๋‹ค.
const obj = Object.create(myProto, {
  y: { value: 20, writable: true, enumerable: true, configurable: true }
});
*/

console.log(obj.x, obj.y); // 10 20
console.log(Object.getPrototypeOf(obj) === myProto); // true

โœ”๏ธ ์ •์  ํ”„๋กœํผํ‹ฐ/๋ฉ”์„œ๋“œ

์ •์  ํ”„๋กœํผํ‹ฐ/๋ฉ”์„œ๋“œ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์•„๋„ ์ฐธ์กฐ/ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ/๋ฉ”์„œ๋“œ๋ฅผ ๋งํ•œ๋‹ค.

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Person(name) {
 this.name = name;
}

// ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ
Person.prototype.sayHello = function () {
 console.log(`Hi! My name is ${this.name}`);
};

// ์ •์  ํ”„๋กœํผํ‹ฐ
Person.staticProp = 'static prop';

// ์ •์  ๋ฉ”์„œ๋“œ
Person.staticMethod = function () {
 console.log('staticMethod');
};

const me = new Person('april');

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์ถ”๊ฐ€ํ•œ ์ •์  ํ”„๋กœํผํ‹ฐ/๋ฉ”์„œ๋“œ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ์ฐธ์กฐ/ํ˜ธ์ถœํ•œ๋‹ค.
Person.staticMethod(); // staticMethod

// ์ •์  ํ”„๋กœํผํ‹ฐ/๋ฉ”์„œ๋“œ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค๋กœ ์ฐธ์กฐ/ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋‹ค.
// ์ธ์Šคํ„ด์Šค๋กœ ์ฐธ์กฐ/ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ/๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ƒ์— ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค.
me.staticMethod(); // TypeError: me.staticMethod is not a function

โœ”๏ธ ํ”„๋กœํผํ‹ฐ ์กด์žฌ ํ™•์ธ

โ˜‘๏ธ in ์—ฐ์‚ฐ์ž

in ์—ฐ์‚ฐ์ž๋Š” ๊ฐ์ฒด ๋‚ด์— ํŠน์ • ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜๋Š” ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•œ๋‹ค.

/**

  • key: ํ”„๋กœํผํ‹ฐ ํ‚ค๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด
  • object : ๊ฐ์ฒด๋กœ ํ‰๊ฐ€ํ•˜๋Š” ํ‘œํ˜„์‹
    */
    key in object
const person = {
  name: 'Lee',
  address: 'Seoul'
};

// person ๊ฐ์ฒด์— name ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
console.log('name' in person);    // true
// person ๊ฐ์ฒด์— address ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
console.log('address' in person); // true
// person ๊ฐ์ฒด์— age ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค.
console.log('age' in person);     // false

in ์—ฐ์‚ฐ์ž ๋Œ€์‹  ES6์—์„œ ๋„์ž…๋œ Reflect.has ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. Reflect.has ๋ฉ”์„œ๋“œ๋Š” in ์—ฐ์‚ฐ์ž์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘

const person = { name: 'Lee'};

console.log(Reflect.has(person. 'name')); // true
console.log(Reflect.has(person. 'toString')); // true

โ˜‘๏ธ Object.prototype.hasOwnProperty ๋ฉ”์„œ๋“œ

Object.prototype.hasOwnProperty ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๊ฐ์ฒด์— ํŠน์ • ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

console.log(person.hasOwnProperty('name')); // true
console.log(person.hasOwnProperty('age')); // true

์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ํ”„๋กœํผํ‹ฐ ํ‚ค๊ฐ€ ๊ฐ์ฒด ๊ณ ์œ ์˜ ํ”„๋กœํผํ‹ฐ ํ‚ค์ธ ๊ฒฝ์šฐ์—๋งŒ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ƒ์†๋ฐ›์€ ํ”„๋กœํ† ํƒ€์ž…์˜ ํ”„๋กœํผํ‹ฐ ํ‚ค์ธ ๊ฒฝ์šฐ false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

โœ”๏ธ ํ”„๋กœํผํ‹ฐ ์—ด๊ฑฐ

โ˜‘๏ธ for.. in๋ฌธ

๊ฐ์ฒด์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์—ด๊ฑฐํ•˜๋ ค๋ฉด for.. in ๋ฌธ์„ ์‚ฌ์šฉํ•œ๋‹ค

for (๋ณ€์ˆ˜์„ ์–ธ๋ฌธ in ๊ฐ์ฒด) {...}

๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ ์ƒ์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ํ”„๋กœํ† ํƒ€์ž…์˜ ํ”„๋กœํผํ‹ฐ ์ค‘์—์„œ ํ”„๋กœํผํ‹ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ [[Enumerable]]์˜ ๊ฐ’์ด true์ธ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์—ด๊ฑฐํ•œ๋‹ค.

๋ฐฐ์—ด์—๋Š” for..in ๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ณ  ์ผ๋ฐ˜์ ์ธ for ๋ฌธ์ด๋‚˜ for.. of ๋ฌธ ๋˜๋Š” Array.prototype.forEach ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ๊ถŒ์žฅํ•œ๋‹ค.

โ˜‘๏ธ Object.keys/values/entries ๋ฉ”์„œ๋“œ

๊ฐ์ฒด ์ž์‹ ์˜ ๊ณ ์œ  ํ”„๋กœํผํ‹ฐ๋งŒ ์—ด๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” for...in ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค Object.keys/values/entries ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅ.
Object.keys ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด ์ž์‹ ์˜ ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ ํ‚ค๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜

const person = {
  name: 'Lee',
  address: 'Seoul',
  __proto__: { age: 20 }
};

console.log(Object.keys(person)); // ["name", "address"]

ES8์—์„œ ๋„์ž…๋œ Object.values ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด ์ž์‹ ์˜ ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜

console.log(Object.values(person)); // ["Lee", "Seoul"]

ES8์—์„œ ๋„์ž…๋œ Object.entries ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด ์ž์‹ ์˜ ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ ํ‚ค์™€ ๊ฐ’์˜ ์Œ์˜ ๋ฐฐ์—ด์„ ๋ฐฐ์—ด์— ๋‹ด์•„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

console.log(Object.entries(person)); // [["name","Lee"], ["address", "Seoul"]]

Object.entries(person).forEach(([key, value]) => console.log(key, value));

/*
name Lee
address Seoul
*/
profile
FrontEnd Developer

0๊ฐœ์˜ ๋Œ“๊ธ€