[ JS ] Prototype
0. ๊ฐ์
js์ ๋ํ ๊น์ ์ดํด๋ฅผ ํตํด ์ต์ ์ ์ฑ๋ฅ์ ๋ผ ์ ์๋ ์น์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์ ์ํด ๊ฐ๋ฐ์ธ์ด๋ก์ JS์ ๊ธฐ๋ณธ์ ๊ณต๋ถํ๊ธฐ๋ก ํ์ต๋๋ค.๊ทธ ์์์ผ๋ก js์ ๊ทผ๊ฐ์ด ๋๋ prototype์ ๋ํ ๊ฐ๋ ๊ณผ ํ์ฉ์ ๋ํ์ฌ ๊ณต๋ถํ์ต๋๋ค.
1. ํ์ต๋ชฉ์
๊ฐ๋ฐ์ธ์ด์ ๊ด์ ์์์ javascript ๋ถ์
๊น์ ์ดํด๋ฅผ ํตํ ์ต์ ํ๋ js ํ๋ก๊ทธ๋๋ฐ ์งํฅ
2. ํ์ต๋ด์ฉ
1) Javascript ์๊ฐ
Javascript๋ ๊ฐ๋ฒผ์ด, ์ธํฐํ๋ฆฌํฐ ํน์ jit (just-in-time) ์ปดํ์ผ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ก, ์ผ๊ธํจ์๋ฅผ ์ง์ํ๋ ํ๋กํ ํ์ ๊ธฐ๋ฐ, ๋ค์ค ํจ๋ฌ๋ค์, ๋จ์ผ ์ค๋ ๋, ๋์ ์ธ์ด ์ ๋๋ค.
- MDN Web Docs
MDN์ ์๊ฐ์ ๊ฐ์ด js๋ ์ฌ๋ฌ๊ฐ์ง ํน์ง์ ๊ฐ์ง, ํนํ ์ด ๊ฒ์๋ฌผ์์ ์์๋ณผ 'ํ๋กํ ํ์ ' ๊ธฐ๋ฐ ์ธ์ด์ ๋๋ค.
2) Javascript ์๋ฃํ
Javascript์๋ ์๋ฃํ์ด ๋ช๊ฐ ์์ต๋๋ค.
boolean, number, string, object์ null, undefined์ด ์ ๋ถ์ ๋๋ค.
๋ฐฐ์ด์ด๋ ํจ์ ๋ฑ ์์ ์ ํ์๋ ๊ฒ์ ์ ์ธํ ๋ชจ๋ ๋ฐ์ดํฐ๋ ์ ๋ถ object, ์ฆ ๊ฐ์ฒด๋ก ๊ตฌํ๋ฉ๋๋ค.
๋ํ, ๊ฐ์ฒด๋ ํจ์๋ฅผ ํตํด์๋ง ์์ฑ๋ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ์๋์ ๊ฐ์ ์ฝ๋๋:
let test_object = {};
๊ฒฐ๊ตญ ์ด๋ฐ ํจ์๋ฅผ ์คํํ๋ ๊ฒ๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๋๋ค:
let test_object = new Object();
3) Prototype
ํ๋ง๋๋ก ์ ๋ฆฌํ์๋ฉด "์์๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํ" ์๋จ์
๋๋ค.
prototype์ ๊ฐ์ฒด์งํฅ์ ์์ ๊ฐ๋ ๊ณผ ๊ฐ์ด ํ๋กํผํฐ(property)๋ ๋ฉ์๋(method)๋ฅผ ์์๋ฐ์ ์ฌ์ฉํ ์ ์๋๋ก ํด์ฃผ๋ ๊ฐ๋ ์ ๋งํฉ๋๋ค. '์๊ธฐ'๋ผ๋ ์ฌ์ ์ ์ ์๋ก ์ดํดํด๋ ๋ฌด๋ฐฉํฉ๋๋ค.
Java ๋ฑ์ ์ธ์ด์๋ ๋ฌ๋ฆฌ, js๋ ์์์์ ์ธ๊ธ๊ณผ ๊ฐ์ด prototype ๊ธฐ๋ฐ ์ธ์ด๋ผ class๋ผ๋ ๊ฐ๋ ์ด ์กด์ฌํ์ง ์์ต๋๋ค.
Class ๊ฐ๋ ์ด ์กด์ฌํ์ง ์๋๋ค๋ ๊ฒ์ ์ฐ๋ฆฌ๊ฐ Java์์ ์ฌ์ฉํ๋ ์์๊ฐ๋ ์ ์ฌ์ฉํ๋๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์๋ฏธํ์ฃ .
๋ฐ๋ผ์ ํจ์จ์ ์ธ ํ๋ก๊ทธ๋๋ฐ์ ์ํด ํ์ํ ์์๊ธฐ๋ฅ์ ๋ฐ๋ผํ๊ธฐ ์ํด ์์ ์ทจ์์ ์ผ๋ก ๊ทธ์ด๋์ ๋ฌธ์ฅ๊ณผ ๊ฐ์ด prototype์ ์ฌ์ฉํด ์์๊ด๊ณ๋ฅผ ํํํฉ๋๋ค.
์ด๋ฅผ ์ํด ๋ชจ๋ ๊ฐ์ฒด์ ๊ทธ ๊ฐ์ฒด์ ๊ทผ๊ฐ์ด ๋๋ ๋ถ๋ชจ๊ฐ์ฒด๋ ์๋ก ์ฐ๊ฒฐ๋์ด์๋๋ฐ, ์ด ์ฐ๊ฒฐ๊ด๊ณ๋ฅผ ์ฒด์ธ (Chain)์ด๋ผ ํฉ๋๋ค.
๋ง์น ์๋ฃ๊ตฌ์กฐ์ LinkedList์ ๋น์ทํ ๋๋์ ๋๋ค.
4) Prototype์ ์ข ๋ฅ
Prototype์ 2๊ฐ์ง ๊ฐ๋ ์ ๋ฌถ์ด์ ๋ถ๋ฅด๋ ๋ง์ ๋๋ค.
์ฒซ๋ฒ์งธ ๋ฌถ์ฌ์๋ ๊ฐ๋ ์ Prototype Object ์ ๋๋ค.
4-1) Prototype Object
Prototype Object๋ ์ด๋ค ํจ์์ ์ ์๋ฅผ ํตํด ์์ฑ๋๋ prototype ์ ๋ณด๋ฅผ ๋ด์ ๊ฐ์ฒด๋ฅผ ๋งํฉ๋๋ค.
๋ณด๋ค ์์ธํ ์ค๋ช ์ ์ํด ๋ธ๋ผ์ฐ์ ์์ง์ด js๋ฅผ ํด์ํ ๋ ์ด๋ฃจ์ด์ง๋ ์์ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ ํตํด ํจ์๋ฅผ ์ ์ํ๋ค๋ฉด:
function Laptop() {}
๋ธ๋ผ์ฐ์ ๋ 2๊ฐ์ง ์์ ์ ๋์์ ์งํํฉ๋๋ค.
1 ) ํจ์์ ์์ฑ์ ์๊ฒฉ ๋ถ์ฌ (Constructor)
'new'๋ผ๋ ํค์๋๋ฅผ ์ฌ์ฉํด๋ณธ ์ ์์๊ฒ๋๋ค.
new ํค์๋๋ ์ด๋ค ๊ฐ์ฒด๋ฅผ ์๋กญ๊ฒ ์์ฑํ๋ ํค์๋๋ฅผ ๋งํฉ๋๋ค.
์ด๋ ๊ฒ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ '์์ฑ์ (Constructor)'๋ผ๊ณ ํ๋๋ฐ, ํจ์๋ ์ ์๋ ๋ ์ด ์๊ฒฉ์ ๋ฐ์ new ํค์๋๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๊ฒ ๋ฉ๋๋ค.
2 ) ํด๋น ํจ์์ ๋ํ Prototype Object ์์ฑ & ์ฐ๊ฒฐ
๋์์ ์ํ๋๋ ๋๋ค๋ฅธ ์์ ์ค ํ๋๋ ์ง๊ธ ๊ณต๋ถ์ค์ธ Prototype Object์ ๋ํ ์์ฑ๊ณผ ์ฐ๊ฒฐ์ ๋๋ค.
์์๊ด์ ์์ ํจ์์ ๋ํ ์ ์ฒด์ฑ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ Prototype Object๋ 'costructor'์ '__proto__'๋ผ๋ 2๊ฐ์ง ์์ฑ์ ๊ฐ์ง๋๋ค.
'constructor' ์์ฑ์ ์ด ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๊ทผ์์ด ๋๋ ํจ์๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
'__proto__'์์ฑ์ Prototype Link์ ๋๋ค.
(์๋์์ ์์ธํ ๋ณด์ง๋ง, Prototype Link๋ ์ฝ๊ฒ๋งํด ๋ค๋ฅธ Prototype Object๋ฅผ ๊ฐ๋ฆฌํค๋ link๋ฅผ ๋งํฉ๋๋ค.)
๋์์, ํจ์์์๋ Prototype Object์ ์ ๊ทผํ๊ธฐ ์ํ ์์ฑ์ด ํ๊ฐ์ง ์๊น๋๋ค.
์ด ์์ฑ์ด ๋ฐ๋ก prototype ์ ๋๋ค.
์ด 2๊ฐ์ง ์์ ์ ์งํํ๋ฉด, ํจ์๋ ๋ค์๊ณผ ๊ฐ์ ์ฐ๊ฒฐ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค.
4-1) Prototype Link (=__proto__)
์์์ ์ทจ์์ค๋ก ๊ทธ์ด๋์ ๋ฌธ์ฅ์ ๋ณด์ ๋ถ๋ค์ ๋์ถฉ ๊ฐ์ ์ก์ผ์ จ๊ฒ ์ง๋ง, Prototype Link๋ ๋ค๋ฅธ Prototype Object๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
์กฐ๊ธ ๋ ์ ํํ ๋งํ์๋ฉด, Prototype Link๋ ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ๊ทธ ์กฐ์์ด์๋ ํจ์์ Prototype Object๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
์์ ์์์์๋ Laptop ํจ์์ Prototype Object์ __proto__ ์์ฑ๊ฐ์ Object์ Prototype Object ์ ๋๋ค.
๋ํ ๋ถ๋ชจ๊ฐ ์๋ ์กฐ์ ํจ์์ Prototype Object๋ฅผ ๊ฐ์ ธ์ค๋ฏ๋ก, Laptop ํจ์ ๋ด๋ถ์ MacbookAir๋ผ๋ ํจ์๊ฐ ์ ์ธ๋์ด๋ ์๋ ๋ฑ์์ด ์ฑ๋ฆฝํฉ๋๋ค. ๋๋ค Object ํจ์์ Prototype Object๋ฅผ ๊ฐ๋ฆฌํค์ฃ .
MacbookAir.prototype.__proto__ === Laptop.prototype.__proto__
์ฃผ์ํ ์ ์ new ํค์๋๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ์ ์ด์ผ๊ธฐ๊ฐ ๋ฌ๋ผ์ง๋ค๋ ์ ์ ๋๋ค.
new ํค์๋๋ฅผ ํตํด ์๋กญ๊ฒ ์์ฑ๋ ๊ฐ์ฒด๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ก ํ ํจ์์ Prototype Object๋ฅผ ์กฐ์์ผ๋ก ํฉ๋๋ค.
ํ์ง๋ง ๋ง์ฝ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ก ํ ํจ์๊ฐ ํน์ ๊ฐ์ ๋ฐํํ๋ค๋ฉด, new ํค์๋๋ฅผ ํตํด ์๋กญ๊ฒ ์์ฑ๋ ๊ฐ์ฒด๋ ๋ฐํ๋๋ ๊ฐ์ ์กฐ์ Prototype Object๋ฅผ __proto__ ์์ฑ๊ฐ์ผ๋ก ํฉ๋๋ค.
์๋๋ ์ ๊ฐ ๊ณต๋ถํ๋ฉด์ ํ ์คํธํด๋ณธ ์ฝ๋์ ๋๋ค.
5) ํ์ฉ
js์ prototype์ ํ์ฉํด ๋ง์ ๊ธฐ๋ฅ๋ค์ ๊ตฌํํ ์ ์์ต๋๋ค.
5-1) ์๋ฃํ ์ ์ญ ๋ฉ์๋ ์ค์
ํน์ ์๋ฃํ์ ํด๋นํ๋ ๋ชจ๋ ๊ฐ์ ๋ํ ์ ์ญ ๋ฉ์๋๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, object array์์ array๋ฅผ ์ ๋ถ string์ผ๋ก ์ถ๋ ฅํด์ผํ๋ ๊ฒฝ์ฐ๊ฐ ์๊ฒผ๋ค๊ณ ํฉ์๋ค.
Array.toString ํจ์๋ ๋ด๋ถ๊ฐ์ด string์ด ์๋๊ธฐ ๋๋ฌธ์ ์ ์์ ์ธ object ๊ฐ์ด ์๋ '[ object Object ]'๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Array์ prototype ๊ฐ์ฒด์ toJSONString์ด๋ผ๋ ๋ฉ์๋๋ฅผ ๋ฑ๋กํฉ๋๋ค.
๊ทธ๋ฌ๋ฉด ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ ํตํด ๋ชจ๋ ๊ฐ์ฒด์์ ๋ณ๋์ ํจ์ ์ ์ธ ์์ด ๋ฐ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค.
Array.prototype.toJSONString = function() {
return this.map(v => JSON.stringify(v)).toString()
}
[{ foo: "bar", admin: "test" }, { foo: "bar2", admin: "test" }].toString()
// '[object Object],[object Object]'
[{ foo: "bar", admin: "test" }, { foo: "bar2", admin: "test" }].toJSONString()
// '{"foo":"bar","admin":"test"},{"foo":"bar2","admin":"test"}'
5-2) ๊ฐ์ฒด์ ์๊ธฐ์์ ์ฐธ์กฐ
๊ฐ์ฒด์ ์์ฑ๊ฐ์ ์ค์ ํ ๋ ์๊ธฐ ์์ ์ ๋ค๋ฅธ ์์ฑ๊ฐ์ด ํ์ํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
๊ทธ๋ด ๋ ๊ฐ์ฒด๋ฅผ ํจ์๋ก ์์ฑํ๊ณ this๋ฅผ returnํ์ฌ ํด๊ฒฐํ ์ ์์ต๋๋ค.
const obj = new function() {
this.foo = "bar";
this.abc = "def";
this.values = this;
return this;
}
console.log(obj); // { foo: "bar", abc: "def", values: { ... } }
๋จ, ์์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์์ฑ๋ ๊ฐ์ฒด๋ JSON.stringify ๊ฐ ๋ถ๊ฐ๋ฅํฉ๋๋ค.