# ํ๋กํ ํ์ (Prototype)
์๋ฐ์คํฌ๋ฆฝํธ๋ ํ๋กํ ํ์
๊ธฐ๋ฐ ์ธ์ด(prototype-based language)
์
๋๋ค. ํ๋กํ ํ์
๊ธฐ๋ฐ ์ธ์ด์์๋ ์ด๋ค ๊ฐ์ฒด๋ฅผ ์ํ(prototype
)์ผ๋ก ์ผ๊ณ ์ด๋ฅผ ์ฐธ์กฐํจ์ผ๋ก์จ ์์๊ณผ ๋น์ทํ ํจ๊ณผ๋ฅผ ์ป์ต๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ์ ํ๋กํ ํ์
์ ์ดํดํ๊ธฐ ์ํด์๋ prototype
์์ฑ์ ์ฐ์ ์ดํดํด์ผ ํฉ๋๋ค. ๊ฐ๋จํ ์์ ๋ก ์์ํด๋ณด๊ฒ ์ต๋๋ค.
# ํ๋กํ ํ์ ๊ฐ๋ ์ดํด
๋ธ๋ผ์ฐ์ ์ ๊ฐ๋ฐ์ ๋๊ตฌ์์ ๊ฐ๋จํ Array๋ฅผ ์ ์ํ ํ ์ถ๋ ฅํด๋ณด๋ฉด ๋ค์ ํ๋ฉด๊ณผ ๊ฐ์ด ๋์ต๋๋ค.
์ถ๋ ฅ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด forEach, map, push์ ๊ฐ์ ์ต์ํ ํจ์๋ค์ด ๋ณด์ ๋๋ค. ์ฐ๋ฆฌ๋ ํด๋น ํจ์๋ฅผ ์ ์ํ์ง ์์๋๋ฐ ๊ทธ๋ผ ์ด๋์ ํจ์๋ค์ด ์ ์๋์ด ์๊ณ , ์ด๋ป๊ฒ ํจ์๋ค์ ์ธ ์ ์๋ ๊ฑธ๊น์?
TIP
__proto__๋ฅผ ์ฝ์ ๋๋ 'dunder proto'('๋๋ ํ๋กํ ')๋ผ๊ณ ์ฝ์ผ๋ฉด ๋ฉ๋๋ค. dunder๋ 'double underscore'์ ์ค์๋ง.
WARNING
__proto__ ์ [[Prototype]]
์๋ฐ์คํฌ๋ฆฝํธ ๋ช
์ธ์๋ __proto__๊ฐ ์๋ [[Prototype]]์ผ๋ก ์ ์๋์ด ์์ผ๋ฉฐ,
__proto__ ์์ฑ์ ๋จ์ง ๋ธ๋ผ์ฐ์ ์์ [[Prototype]]์ ๊ตฌํํ ๋์์ด๋ฉฐ ๊ถ์ฅ๋๋ ๋ฐฉ์์ด ์๋๋๋ค. ๊ถ์ฅ๋๋ ๋ฐฉ์์ ํ๋จ์ ์ฐธ๊ณ ๋งํฌ๋ฅผ ํ์ธํด์ฃผ์ธ์. ์ต์ ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ์์๋ __proto__๊ฐ ์๋ [[Prototype]]์ผ๋ก ํํ๋ ์ ์์ต๋๋ค. ๋ณธ ๋ฌธ์์์๋ ์ดํดํ๊ธฐ ์ฝ๊ฒ ํ๊ธฐ ์ํ์ฌ ์ค๋ช
๊ณผ ์ฌ์ง์ __proto__ ์์ฑ์ ์ฌ์ฉํ์์ต๋๋ค.
# prototype ์์ฑ๊ณผ __proto__ ์์ฑ
๋ฐ๋ก ์ ์์ ์์ ์ฌ์ฉํ ์์ ๋ฅผ ๋ค๋ฅด๊ฒ ํํํ๋ฉด ๋ค์์ new ํค์๋๋ฅผ ์ฌ์ฉํ๋ ๋ฌธ์ฅ๊ณผ ๋์ผํฉ๋๋ค.
// var simpleArray = [];
var simpleArray = new Array();
์ ๋ฌธ์ฅ์ ์คํํ๋ฉด ์ผ์ด๋๋ ์ผ์ ์์๋๋ก ์ค๋ช ํ๋ฉด
- ์์ฑ์ ํจ์ Array๋ฅผ new ํค์๋์ ํจ๊ป ํธ์ถํ๋ฉด
- ์์ฑ์ ํจ์ Array์ ์ ์๋ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์๋ก์ด ์ธ์คํด์ค simpleArray๊ฐ ์์ฑ๋ฉ๋๋ค.
- ์ด๋ ์์ฑ๋ ์ธ์คํด์ค์ธ simpleArray์๋
__proto__
๋ผ๋ ์์ฑ์ด ์๋์ผ๋ก ๋ถ์ฌ๋๋๋ฐ __proto__
์์ฑ์ ์์ฑ์ ํจ์ Array์prototype
์์ฑ์ ์ฐธ์กฐํฉ๋๋ค.
๊ฐ๋ฐ์ ๋๊ตฌ์์ ๋ค์ Array.prototype ์ ์ถ๋ ฅํด๋ณด๋ฉด, ์์์ ์ถ๋ ฅํ simpleArray์ __proto__
์์ฑ์ ๋ด์ฉ๊ณผ ๋์ผํ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์ฆ, ์ฐ๋ฆฌ๊ฐ ๋งจ ์ฒ์ ์์ ์์ ๋ดค๋ 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 ํจ์๊ฐ ์ด๋์ ์ ์๋์ด ์๋์ง ํ์ธ ํ ์ ์์ต๋๋ค.
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) ๋ฌธ์์ ๋์จ ๊ฐ์ฒด ๋ฌธ์์ '์ธ์คํด์ค'๋ 'ํ๋กํ ํ์
' ๋ถ๋ถ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.