# ํ”„๋กœํ† ํƒ€์ž… (Prototype)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜ ์–ธ์–ด(prototype-based language) ์ž…๋‹ˆ๋‹ค. ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜ ์–ธ์–ด์—์„œ๋Š” ์–ด๋–ค ๊ฐ์ฒด๋ฅผ ์›ํ˜•(prototype)์œผ๋กœ ์‚ผ๊ณ  ์ด๋ฅผ ์ฐธ์กฐํ•จ์œผ๋กœ์จ ์ƒ์†๊ณผ ๋น„์Šทํ•œ ํšจ๊ณผ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ”„๋กœํ† ํƒ€์ž…์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” prototype ์†์„ฑ์„ ์šฐ์„  ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋กœ ์‹œ์ž‘ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

# ํ”„๋กœํ† ํƒ€์ž… ๊ฐœ๋… ์ดํ•ด

๋ธŒ๋ผ์šฐ์ €์˜ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ๊ฐ„๋‹จํ•œ Array๋ฅผ ์ •์˜ํ•œ ํ›„ ์ถœ๋ ฅํ•ด๋ณด๋ฉด ๋‹ค์Œ ํ™”๋ฉด๊ณผ ๊ฐ™์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

simpleArray ์ถœ๋ ฅ ๊ฒฐ๊ณผ

์ถœ๋ ฅ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด forEach, map, push์™€ ๊ฐ™์€ ์ต์ˆ™ํ•œ ํ•จ์ˆ˜๋“ค์ด ๋ณด์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ ๊ทธ๋Ÿผ ์–ด๋””์— ํ•จ์ˆ˜๋“ค์ด ์ •์˜๋˜์–ด ์žˆ๊ณ , ์–ด๋–ป๊ฒŒ ํ•จ์ˆ˜๋“ค์„ ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ฑธ๊นŒ์š”?

TIP

__proto__๋ฅผ ์ฝ์„ ๋•Œ๋Š” 'dunder proto'('๋˜๋” ํ”„๋กœํ† ')๋ผ๊ณ  ์ฝ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. dunder๋Š” 'double underscore'์˜ ์ค„์ž„๋ง.

WARNING

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

์ฐธ๊ณ  : "ํ”„๋กœํ† ํƒ€์ž… ์ƒ์†" ๋ฌธ์„œ '__proto__๋Š” [[Prototype]]์šฉ getterยทsetter์ž…๋‹ˆ๋‹ค.' ๋ถ€๋ถ„ (opens new window)

# prototype ์†์„ฑ๊ณผ __proto__ ์†์„ฑ

๋ฐ”๋กœ ์œ„ ์˜ˆ์ œ์—์„œ ์‚ฌ์šฉํ•œ ์˜ˆ์ œ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ์˜ new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์žฅ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

// var simpleArray = [];
var simpleArray = new Array();

์œ„ ๋ฌธ์žฅ์„ ์‹คํ–‰ํ•˜๋ฉด ์ผ์–ด๋‚˜๋Š” ์ผ์„ ์ˆœ์„œ๋Œ€๋กœ ์„ค๋ช…ํ•˜๋ฉด

  1. ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Array๋ฅผ new ํ‚ค์›Œ๋“œ์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜๋ฉด
  2. ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Array์— ์ •์˜๋œ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค simpleArray๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  3. ์ด๋•Œ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค์ธ simpleArray์—๋Š” __proto__ ๋ผ๋Š” ์†์„ฑ์ด ์ž๋™์œผ๋กœ ๋ถ€์—ฌ๋˜๋Š”๋ฐ
  4. __proto__ ์†์„ฑ์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Array์˜ prototype ์†์„ฑ์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ๋‹ค์‹œ Array.prototype ์„ ์ถœ๋ ฅํ•ด๋ณด๋ฉด, ์œ„์—์„œ ์ถœ๋ ฅํ•œ simpleArray์˜ __proto__ ์†์„ฑ์˜ ๋‚ด์šฉ๊ณผ ๋™์ผํ•œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Array.prototype ์ถœ๋ ฅ ๊ฒฐ๊ณผ

์ฆ‰, ์šฐ๋ฆฌ๊ฐ€ ๋งจ ์ฒ˜์Œ ์˜ˆ์ œ์—์„œ ๋ดค๋˜ forEach, map, push์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋“ค์€ Array.prototype์— ์ •์˜๋˜์–ด ์žˆ๊ณ , simpleArray ์ธ์Šคํ„ด์Šค์˜ __proto__ ์†์„ฑ์—์„œ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Array.prototype === simpleArray.__proto__; //true

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

# prototype ์†์„ฑ ์‚ฌ์šฉ ์˜ˆ์ œ

๋‹ค์Œ์œผ๋กœ prototype ์†์„ฑ์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด prototype ์†์„ฑ์„ ๋” ์ดํ•ดํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค

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

// ๋ชจ๋“  ํ•จ์ˆ˜๋Š” prototype ์†์„ฑ์„ ์ž๋™์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Œ
Person.prototype.printName = function() {
  console.log(this.name);
};

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด Person์ด๋ผ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ์— printName ์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ Person์˜ ์ธ์Šคํ„ด์Šค๋Š” __proto__ ์†์„ฑ์„ ํ†ตํ•ด printName ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ...

var ironMan = new Person("Tony Stark");
ironMan.__proto__.printName(); // undefined

์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์„ค์ •ํ•œ ์ด๋ฆ„์ธ 'Tony Stark'๊ฐ€ ์•„๋‹Œ undefined๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ๋Š” ๋ฉ”์„œ๋“œ ๋ฐ”๋กœ ์•ž์˜ ๊ฐ์ฒด๊ฐ€ this๊ฐ€ ๋˜๋Š”๋ฐ, ironMan.__proto__์—๋Š” name์ด๋ผ๋Š” ์†์„ฑ์ด ์กด์žฌํ•˜์ง€ ์•Š์•„ undefined๊ฐ€ ์ถœ๋ ฅ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์šฐ๋ฆฌ๊ฐ€ ์„ค์ •ํ•œ ์ด๋ฆ„์„ ์ถœ๋ ฅํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด this๋ฅผ ironMan ์ธ์Šคํ„ด์Šค๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ __proto__ ์—†์ด ์ธ์Šคํ„ด์Šค์—์„œ ๋ฐ”๋กœ printName ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

// ...

var ironMan = new Person("Tony Stark");
ironMan.printName(); // Tony Stark

var captainAmerica = new Person("Steve Rogers");
captainAmerica.printName(); // Steve Rogers

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

captainAmerica.__proto__.printName();
-> captainAmerica(.__proto__.)printName();
-> captainAmerica.printName();

# ํ”„๋กœํ† ํƒ€์ž… ๊ฐœ๋… ์ •๋ฆฌ

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

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

# ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ

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

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

Person.prototype.printName = function() {
  console.log(this.name);
};

var ironMan = new Person("Tony Stark");

//printName ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ
ironMan.printName = function() {
  console.log(`I am ${this.name}`);
};

ironMan.printName(); // I am Tony Stark

์œ„ ์˜ˆ์ œ๋Š” ์œ„์—์„œ ์‚ฌ์šฉ ์˜ˆ์ œ์—์„œ ironMan ์ธ์Šคํ„ด์Šค์— printName ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค์‹œ ์ •์˜ํ•œ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด, ironMan.__proto__.printName์ด ์•„๋‹Œ, ironMan ๊ฐ์ฒด์— ์žˆ๋Š” printName ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ํ˜„์ƒ์„ '๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ(method override)' ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์„œ๋“œ ์œ„์— ๋ฉ”์„œ๋“œ๋ฅผ ๋ฎ์–ด์”Œ์› ๋‹ค ๋Š” ํ‘œํ˜„์œผ๋กœ, ์›๋ณธ์„ ์ œ๊ฑฐํ•˜๊ณ  ๋‹ค๋ฅธ ๋Œ€์ƒ์œผ๋กœ ๊ต์ฒดํ•œ ๊ฒƒ์ด ์•„๋‹Œ ์›๋ณธ ๊ทธ๋Œ€๋กœ ์žˆ๋Š” ์ƒํƒœ์—์„œ ๋‹ค๋ฅธ ๋Œ€์ƒ์„ ์œ„์— ์–น๋Š” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์ด printName์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ๋Š” ๋ฐฉ์‹์€ ๋จผ์ € ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ์†์„ฑ๋“ค์„ ๊ฒ€์ƒ‰ํ•˜๊ณ , ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด __proto__ ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๋Š” ์ˆœ์„œ๋กœ ์ง„ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ironMan ๊ฐ์ฒด์— ์žˆ๋Š” printName ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

# ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ด๋‹

๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์œผ๋‹ˆ ๋งจ ์ฒ˜์Œ์œผ๋กœ ๋Œ์•„๊ฐ€ Array๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ๋ฅผ ๋‹ค์‹œ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

var simpleArray = new Array(1, 2); //[1, 2]
simpleArray.push(3); //[1, 2, 3]
simpleArray.hasOwnProperty(2); // true

simpleArray ์ธ์Šคํ„ด์Šค์— push ํ•จ์ˆ˜์™€ hasOwnProperty ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ, ์œ„์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์ด ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ๋Š” ๋ฐฉ์‹์ด ๋จผ์ € ์ž์‹ ์˜ ์†์„ฑ์„ ๊ฒ€์ƒ‰ํ•˜๊ณ , ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ทธ๋‹ค์Œ์œผ๋กœ ๊ฐ€๊นŒ์šด ๋Œ€์ƒ์ธ __proto__ ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ์ˆœ์„œ๋กœ ์ง„ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์ œ์—์„œ console.dir(simpleArray); ๋ช…๋ น์„ ์‹คํ–‰ํ•ด๋ณด๋ฉด, push ํ•จ์ˆ˜์™€ hasOwnProperty ํ•จ์ˆ˜๊ฐ€ ์–ด๋””์— ์ •์˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

console.dir(simpleArray)์˜ ๊ฒฐ๊ณผ

simpleArray(.__proto__).push(3);
// simpleArray.__proto__ === Array.prototype // true

simpleArray(.__proto__)(.__proto__).hasOwnProperty();
// simpleArray.__proto__.__proto__ === Object.prototype // true

์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ–ˆ๋˜ ํ•จ์ˆ˜๋“ค์€ ์‚ฌ์‹ค ์œ„์™€ ๊ฐ™์ด Array.prototype์— ์ •์˜๋œ push ํ•จ์ˆ˜์™€ Object.prototype์— ์ •์˜๋œ hasOwnProperty ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์–ด๋–ค ๋ฐ์ดํ„ฐ์˜ __proto__ ์†์„ฑ ๋‚ด๋ถ€์— ๋‹ค์‹œ __proto__ ์†์„ฑ์ด ์—ฐ์‡„์ ์œผ๋กœ ์ด์–ด์ง„ ๊ฒƒ์„ 'ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ(prototype chain)' ์ด๋ผ ํ•˜๊ณ , ์ด ์ฒด์ธ์„ ๊ณ„์† ๋”ฐ๋ผ๊ฐ€๋ฉฐ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ์„ 'ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ด๋‹(prototype chaining)' ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์œ„์—์„œ ์„ค๋ช…ํ•œ push ํ•จ์ˆ˜์™€ hasOwnProperty ํ•จ์ˆ˜๋ฅผ '์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์žฅํ•จ์ˆ˜' ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์žฅํ•จ์ˆ˜๋Š” Array์™€ Object์™€ ๊ฐ™์€ '์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ‘œ์ค€ ๋‚ด์žฅ ๊ฐ์ฒด' ์˜ prototype ์— ์ •์˜๋˜์–ด ์žˆ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ MDN ํ‘œ์ค€ ๋‚ด์žฅ ๊ฐ์ฒด (opens new window) ๋ฌธ์„œ์— ๋‚˜์˜จ ๊ฐ์ฒด ๋ฌธ์„œ์˜ '์ธ์Šคํ„ด์Šค'๋‚˜ 'ํ”„๋กœํ† ํƒ€์ž…' ๋ถ€๋ถ„์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.