์ด ๋ธ๋ก๊ทธ ์ฝํ ์ธ ์๋ ์ฑ '์ฝ์ด ์๋ฐ์คํฌ๋ฆฝํธ'๋ฅผ ์ฝ๊ณ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๊น๊ฒ ์ดํดํ๋ ๋ด์ฉ์ด ๋ด๊น๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ํ๋กํ ํ์
์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ํ๋กํ ํ์ ๊ธฐ๋ฐ์ ์ธ์ด๋ผ๋ ์ ์ ๋ง์ด ๋ค์ด์ ์๊ณ ์์ ๊ฒ์ด๋ค. ํด๋์ค ๊ธฐ๋ฐ์ ์ธ์ด์ ์๋ ์์๊ณผ๋ ๋ค๋ฅด๊ฒ ํน์ ํ ๊ฐ์ฒด ํ๋๋ฅผ ์ํ(prototype)์ผ๋ก ์ผ๊ณ ์ด๋ฅผ ๋ณต์ ํ๋ ๋ฐฉ์์ผ๋ก ์์์ ํ๋ด๋ธ๋ค. ํ๋กํ ํ์ ์ ๊ฐ๋ ์ ํ ๋ฒ ์ดํดํ๋ ๊ฒ์ด ์ด๋ ต์ง๋ง ์ด๋ฒ์ ํด๋ด๋ณด์.
๊ธฐ๋ณธ
์์ ์ด๋ฏธ์ง์ ํ๋ฆ์ ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
- ์ด๋ค ์์ฑ์ ํจ์๋ฅผ new ํค์๋์ ํจ๊ป ํธ์ถํ๋ฉด ์์ฑ์์์ ์ ์๋ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์๋ก์ด ์ธ์คํด์ค(instance)๊ฐ ์์ฑ๋๋ค.
- ์ธ์คํด์ค๊ฐ ์์ฑ๋ ๋
__proto__
๋ผ๊ณ ํ๋ ํ๋กํผํฐ๊ฐ ์๋์ผ๋ก ๋ถ์ฌ๋๋ค. __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์ด ์ฐ๊ฒฐ๋๊ธฐ ๋๋ฌธ์ด๋ค. ์๋์ ๊ทธ๋ฆผ์ฒ๋ผ ์ฐ๊ฒฐ๋์ด ์๋ ๊ฒ์ด๋ค.
proto๋ ์๋ต์ด ๊ฐ๋ฅํ ํ๋กํผํฐ์ด๊ธฐ ๋๋ฌธ์ ๋ฐฐ์ด์ Object.prototype์ ๋ด๋ถ ๋ฉ์๋๋ฅผ ์์ ์ ๊ฒ์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค. array(.__proto__)(.__proto__).hasOwnProperty();
์ด๋ ๊ฒ ๋ง์ด๋ค.
์ด๋ฐ ๊ฒ์ฒ๋ผ __proto__
ํ๋กํผํฐ ๋ด๋ถ์ __proto__
ํ๋กํผํฐ๊ฐ ์ฐ์์ ์ผ๋ก ์ด์ด์ง ํํ๋ฅผ ํ๋กํ ํ์
์ฒด์ธ์ด๋ผ๊ณ ํ๋ค. ์ด ์ฒด์ธ์ ๋ฐ๋ผ๊ฐ๋ฉฐ ๊ฒ์ํ๋ ๊ณผ์ ์ ํ๋กํ ํ์
์ฒด์ด๋์ด๋ผ๊ณ ํ๋ค.