๐Ÿ‘จโ€๐Ÿ’ป

JavaScript ํ”„๋กœํ† ํƒ€์ž…

2021-06-30 ย  | ย  ๊ฐœ๋ฐœ JavaScript

post-img

์ด ๋ธ”๋กœ๊ทธ ์ฝ˜ํ…์ธ ์—๋Š” ์ฑ… '์ฝ”์–ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ'๋ฅผ ์ฝ๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊นŠ๊ฒŒ ์ดํ•ดํ•˜๋Š” ๋‚ด์šฉ์ด ๋‹ด๊น๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ”„๋กœํ† ํƒ€์ž…

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



๊ธฐ๋ณธ

prototype

์œ„์˜ ์ด๋ฏธ์ง€์˜ ํ๋ฆ„์„ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

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

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

const Person = function (name) { this._name = name; }; Person.prototype.getName = function () { return this._name; }; const dobby = new Person('Dobby'); dobby.__proto__.getName(); //undefined

์œ„์˜ ์˜ˆ์‹œ์—์„œ dobby.__proto__.getName()์„ ์ฐ์–ด๋ณด๋ฉด undefined๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ํ•จ์ˆ˜๋ฅผ ๋ฉ”์„œ๋“œ๋กœ ํ˜ธ์ถœํ•˜๋ฉด '.' ์•ž์˜ ๊ฐ์ฒด๊ฐ€ ๋ฐ”๋กœ this๊ฐ€ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ getName ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฌถ์ธ this๋Š” dobby.__proto__ ๊ฐ์ฒด๊ฐ€ ๋œ๋‹ค. ์ด ๊ฐ์ฒด ๋‚ด๋ถ€์—๋Š” 'name'์ด๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ •์˜๋˜์ง€ ์•Š์€ ์‹๋ณ„์ž๋ฅผ ์ฐพ์„๋•Œ ๋ฑ‰๋Š” undefined๊ฐ€ ๋‚˜์˜จ ๊ฒƒ์ด๋‹ค.

dobby.__proto__.name = 'Dobby'; dobby.__proto__.getName(); // 'Dobby' dobby.getName(); // 'Dobby'

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

์ •๋ฆฌํ•˜๋ฉด, 'new Constructor() ํ˜•ํƒœ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์ƒ๋žต ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ __proto__๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์ด๊ฒƒ์€ Constructor์˜ prototype ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.'

Array๋ผ๊ณ  ํ•˜๋Š” ์ƒ์„ฑ์ž๋ฅผ ์ง์ ‘ ์ฝ˜์†”์— ์ฐ์–ด๋ณด๋ฉด prototype๊ณผ ๊ธฐ๋ณธ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.



prototype ๊ฐ์ฒด ๋‚ด๋ถ€์˜ constructor ํ”„๋กœํผํ‹ฐ

์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ๊ฐ์ฒด์—๋Š” constructor๋ผ๊ณ  ํ•˜๋Š” ์ž๊ธฐ ์ž์‹ ์„ ์ฐธ์กฐํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋‹ค. ์ƒ์„ฑ๋œ __proto__ ๊ฐ์ฒด์—๋„ ์กด์žฌํ•œ๋‹ค. ์ด๊ฒƒ์€ ์ธ์Šคํ„ด์Šค์™€์˜ ๊ด€๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์ •๋ณด์ธ๋ฐ, ์ธ์Šคํ„ด์Šค์˜ ์›ํ˜•์ด ๋ฌด์—‡์ธ์ง€๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ ์—ญํ• ์„ ํ•œ๋‹ค.

const array = [1, 2]; Array.prototype.constructor === Array; // true array.__proto__.constructor === Array; // true array.constructor === Array; // true const array2 = new array.constructor(3, 4); console.log(array2); // [3, 4]



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

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

prototype ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” __proto__๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ธ์Šคํ„ด์Šค๋Š” prototype์— ์ •์˜๋œ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค. ์•„๋ž˜์˜ ์˜ˆ์‹œ๋ฅผ ํ•œ ๋ฒˆ ๋ณด์ž.

const Person = function (name) { this.name = name; }; Person.prototype.getName = function () { return this.name; }; const IU = new Person('์ด์ง€์€'); IU.getName = function () { return 'IU๋Š” ' + this.name + '์ด๋‹ค.'; }; console.log(IU.getName()); // 'IU๋Š” ์ด์ง€์€์ด๋‹ค.' console.log(IU.__proto__.getName.apply(IU)); // '์ด์ง€์€'

IU ์ธ์Šคํ„ด์Šค์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. Person prototype ๊ฐ์ฒด์— ๋“ฑ๋ก๋œ getName ๋ฉ”์„œ๋“œ์™€ ๋™์ผํ•œ ํ•จ ์ˆ˜ ๋ช…์ด๊ธฐ ๋•Œ๋ฌธ์— ์›๋ณธ์ด ์žˆ๋Š” ๊ทธ ์ƒํƒœ์—์„œ ๋‹ค๋ฅธ ๋Œ€์ƒ์„ ์–น์€ ๊ฒƒ์ด๋‹ค.

์˜ค๋ฒ„๋ผ์ด๋”ฉ ๋˜์ง€ ์•Š๊ณ , prototype์— ๋“ฑ๋ก๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋™์ž๊ฐ€ํ—ค ํ•˜๋ ค๋ฉด, IU ์ธ์Šคํ„ด์Šค์— ์žˆ๋Š” __proto__์—๋‹ค๊ฐ€ IU ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ”๋ผ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋“ฑ๋กํ•˜๋ฉด ๋œ๋‹ค. call, apply ๋ฉ”์„œ๋“œ๋กœ ๋ฐ”์ธ๋”ฉ์„ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ์›๋ณธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์šฐํšŒ๋ฅผ ํ•ด์•ผํ•œ๋‹ค๋Š” ์ ์ด ์žˆ๋‹ค.


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

console.dir([1, 2])๋ฅผ ์ฐ์–ด๋ณด๋ฉด ์šฐ๋ฆฌ์—๊ฒŒ ์ต์ˆ™ํ•œ pop, push์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ __proto__ ํ”„๋กœํผํ‹ฐ ์•ˆ์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. constructor๋Š” f Array()๋กœ ๋ฐฐ์—ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฅดํ‚ค๊ณ  ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ proto์•ˆ์— ๋˜ ๋‹ค๋ฅธ proto๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๊ฒƒ์€ console.dir({a: 1})์„ ์ฐ์–ด๋ดค์„ ๋•Œ์˜ proto์™€ ๋™์ผํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋“  ๊ฐ์ฒด์˜ proto์— Object.prototype์ด ์—ฐ๊ฒฐ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์•„๋ž˜์˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

prototype

proto๋Š” ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์—ด์€ Object.prototype์˜ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. array(.__proto__)(.__proto__).hasOwnProperty(); ์ด๋ ‡๊ฒŒ ๋ง์ด๋‹ค.

์ด๋Ÿฐ ๊ฒƒ์ฒ˜๋Ÿผ __proto__ ํ”„๋กœํผํ‹ฐ ๋‚ด๋ถ€์— __proto__ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—ฐ์‡„์ ์œผ๋กœ ์ด์–ด์ง„ ํ˜•ํƒœ๋ฅผ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ด ์ฒด์ธ์„ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ณผ์ •์„ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ด๋‹์ด๋ผ๊ณ  ํ•œ๋‹ค.

๋ชฉ์ฐจ

์ด์–ด์ง€๋Š” ๊ธ€,