11-1. ํ๋กํ ํ์
์ฌ์ฉ ์ฌ๋ก11-2. ํ๋กํ ํ์
์ ์ ์11-2-1. ์์ฑ์ ํจ์์ ํ๋กํ ํ์
11-2-2. ์์ฑ์์ ํ๋กํ 11-2-3. ๊ฐ์ ๊ฐ์ ๊ฐ์ง ํ๋กํ 11-2-4. ํ๋กํ ํ์
๊ฐ์ ์ํต ๊ณต์ ๋ฒ์11-3. ํ์
์์ ํ๋กํ ํ์
๊ณผ ์์ฑ์๋ฅผ ์ฌ์ฉ ๋ฐฉ๋ฒ
11-1. ํ๋กํ ํ์ ์ฌ์ฉ ์ฌ๋ก
์๋ฐ์คํฌ๋ฆฝํธ์์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๊ตฌํํ๋ ๋ฐฉ์์ผ๋ก๋ ํ๋กํ ํ์
์์, ๊ฐ์ฒด ๋ฆฌํฐ๋ด ๋ฑ์ด ์๋ค. ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ํจ์๋ ํ๋กํ ํ์
์ ๊ฐ์ง๋ฉฐ, ๋นํธ์ธ ์ค๋ธ์ ํธ ๋ํ ํ๋กํ ํ์
์ด ์๋ค. ๋ง์ฝ ํ๋กํ ํ์
์ด ์์ผ๋ฉด ํจ์๋ ์๋ช
์ด ๋๋๋ฉฐ ํด๋น ํจ์์ ์ธ์คํด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋๋ค.
ํ๋กํ ํ์
์ ๊ฐ์ง๋ ๋นํธ์ธ ์ค๋ธ์ ํธ๋ค

11-2. ํ๋กํ ํ์ ์ ์ ์
๋ชจ๋ ๊ฐ์ฒด๋ ํ๋กํ ํ์
๊ฐ์ฒด๋ฅผ ๊ฐ์ง๋ฉฐ, ์ด ํ๋กํ ํ์
๊ฐ์ฒด๋ ํด๋น ๊ฐ์ฒด์ ๊ธฐ๋ฅ๊ณผ ์์ฑ์ ์ ์ํ๋ค. ๊ฐ์ฒด์ ์์ฑ๊ณผ ๋ฉ์๋๋ ํ๋กํ ํ์
๊ฐ์ฒด์์ ์์๋๋ค. ์ด๋ ๊ฒ ์์ ๊ด๊ณ๋ฅผ ํตํด โ๊ฐ์ฒดโ ๊ฐ์ ๊ณตํต๋ ๊ธฐ๋ฅ์ ์ฌ์ฌ์ฉํ ์ ์๋ค.
11-2-1. ์์ฑ์ ํจ์์ ํ๋กํ ํ์
์์ฑ์ ํจ์๋ฅผ ๋ง๋ค๋ฉด ์๋์ผ๋ก ํ๋กํ ํ์
์ด ํฌํจ๋๋ค.
// ์์ฑ์ ํจ์ function Person(name) { this.name = name; } // ํ๋กํ ํ์ ์ ๋ฉ์๋ ์ถ๊ฐ Person.prototype.greet = function() { console.log(`Hello, my name is ${this.name}`); }; // ๊ฐ์ฒด ์์ฑ const person1 = new Person('Alice'); const person2 = new Person('Bob'); // ๋ฉ์๋ ํธ์ถ person1.greet(); // ์ถ๋ ฅ: Hello, my name is Alice person2.greet(); // ์ถ๋ ฅ: Hello, my name is Bob
์ ๋ฐฉ๋ฒ์ฒ๋ผ Person์ ์ ์ํ์ฌ person1์ person2์ greet() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ฌ์ฉํ ์ ์๋ค
11-2-2. ์์ฑ์์ ํ๋กํ
๋น์ทํ ๊ฐ์ฒด๋ค์ ๋น์ทํ ์์
์ ์ํํ ์ ์์ด์ผ ํ๋ฏ๋ก, ๊ณตํต๋ ๊ธฐ๋ฅ์ ๊ณต์ ํ๋ ๊ฒ์ด ํจ์จ์ ์ด๋ค. ํ์ง๋ง ๋๋ก๋ ๊ฐ์ฒด๋ค์ด ๊ฐ์ ๋
๋ฆฝ์ ์ธ ์์
์ ์ํํด์ผ ํ๋ ์ํฉ๋ ์๋ค.
function Taiyaki(){ this.filling = "ํฅ"; } const taiyaki1 = new Taiyaki(); const taiyaki2 = new Taiyaki(); //taiyaki1์ ํ๋กํ ์ ์ฐ์ taiyaki1.__proto__.setFilling = function(ReFilling){ this.filling = ReFilling return this.filling+"์ผ๋ก ์ฑ์ด๋ค" } //taiyaki1์ ํฌ๋กํ ํ์ ์ ์ฐ์ taiyaki1.eat = function(newFilling){ return this.filling + "์ ๋จน๋ค" } console.log(taiyaki1.setFilling("ํฌ๋ฆผ")) // ํฌ๋ฆผ์ผ๋ก ์ฑ์ด๋ค console.log(taiyaki1.eat()) // ํฌ๋ฆผ ๋จน๋ค console.log(taiyaki2.setFilling("์น์ฆ")) // ์น์ฆ์ผ๋ก ์ฑ์ด๋ค console.log(taiyaki2.eat()) // ์๋ฌ
์์ ๋ก์ง์ ๋ณด๋ฉด console.log(taiyaki2.eat()) ์์ ์๋ฌ๊ฐ ๋ ์ผ ํ๋ค.
์์ง ํ๋ฆฌ์ง ์์ taiyaki2 ๋ ์์ ์ด ์ด๋ ํ ๋ชฉ์ ์ผ๋ก ๊ตฌ๋งคํ์๋์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ๋ฉ์๋๋ฅผ ์ถ๊ฐ ํ์ง ์๋ ๊ฒ์ด ์ฌ๋ฐ๋ฅด๋ค. ๊ทธ๋์ eat()์ด๋ผ๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํด์ผ ํ๋ค.
taiyaki1.__proto__.setFilling = function(ReFilling){ this.filling = ReFilling return this.filling+"์ผ๋ก ์ฑ์ด๋ค" }
๋ฐ๋ฉด setFilling ์ด๋ผ๋ ๋ด์ฉ์ ๋ฐ๊พธ๋ ์ํ๋ ๋ชจ๋ ๊ฐ์ฒด๊ฐ ์ ์ ์์ด์ผ ํ๋ค.
๊ทธ๋ฌํ๊ธฐ ์ํด proto ์ ํจ์๋ฅผ ๋ฃ์๋ค proto ์ ํจ์๋ฅผ ๋ฃ์ ์์์ ๊ฐ์ ์์ฑ์๋ฅผ ์ฌ์ฉํ ๊ฐ์ฒด์ ๊ณต์ ํ๋ค.
taiyaki1.eat = function(newFilling){ return this.filling + "์ ๋จน๋ค" }
๋จน๋๋ค๋ ํ๋จ์ ํ๋ฆฐ ๊ฐ์ฒด taiyaki1๋ง ์์์ผ ํ๋ค.
๋ง์ผ ๋จน์ง ์๊ณ ๋ค๋ฅธ ์ฌ๋ํํ
์๋ํ๊ฑฐ๋ ๋ณด๊ดํ๋ค๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์๋ ์๊ณ , ๊ฒฐ๊ตญ ๋ง์ง๋ง์ ๋จน์ง๋ ๋ชปํ๊ณ ๋ฒ๋ฆด ์๋ ์๋ค. ๊ทธ๋์ taiyaki1 ํ๋กํ ํ์
์ ๋ฃ์ด์ ํด๋น ๊ฐ์ฒด๋ง ์คํํ ์ ์๋ ํจ์๋ฅผ ๋ฃ์ด, ๋ค๋ฅธ ๊ฐ์ฒด์์ ์ค๋ฅ๋ฅผ ์ผ์ผํฌ ๋งํ ๋ฉ์๋๋ฅผ ์ฃผ์ง ์๋ ๊ฒ์ด ๋ฐ๋์งํ๋ค.
11-2-3. ๊ฐ์ ๊ฐ์ ๊ฐ์ง ํ๋กํ
๊ฐ์ฒด์์ ํ๋กํ ํ์
๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ๋งํฌ๋ฅผ ๊ฐ์ง๋ฉฐ, ์ด ๋งํฌ๋ฅผ ๋ฐ๋ผ ์์ ํ๋กํ ํ์
๊ฐ์ฒด๋ฅผ ์ฐพ๋ ๊ณผ์ ์ ํ๋กํ ํ์
์ฒด์ธ์ด๋ผ๊ณ ํ๋ค. ๋ง์ฝ ๊ฐ์ฒด์์ ์ด๋ค ์์ฑ์ด๋ ๋ฉ์๋๋ฅผ ์ฐพ์ ์ ์์ ๋๋ ์ด ์ฒด์ธ์ ๋ฐ๋ผ ์์ ํ๋กํ ํ์
๊ฐ์ฒด์์ ์ฐพ๋๋ค.
์์ฑ์ ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ๋ณธ์ ์ธ ํ๋กํ ํ์
์ ๊ณต์ ๋๋ค.
function Person(name) { this.name = name; } let person = new Person('John'); console.log(person.__proto__=== Person.prototype); // true
์์ฒ๋ผ ํ๋กํ ํ์
์ ๊ทธ๋๋ก ๋ค๊ณ ์์ ๋ถ๋ชจ์ ์๋ prototype๊ณผ __proto__๋ ์์ ํ ๊ฐ๋ค.
์ด๋ ๊ฒ ์์ ํ ๊ฐ์ผ๋ฉด ๋ ๊ฐ์ ํด๋์ค๋ฅผ ํฉ์น๋ ๊ฒ ๋ํ ๊ฐ๋ฅํ๋ค.
// ๋ถ๋ชจ ์์ฑ์ ํจ์ function Animal(name) { this.name = name; } // ๋ถ๋ชจ ์์ฑ์ ํจ์์ ํ๋กํ ํ์ ์ ๋ฉ์๋ ์ถ๊ฐ Animal.prototype.sayName = function() { console.log(`I am ${this.name}`); }; // ์์ ์์ฑ์ ํจ์ function Dog(name, breed) { Animal.call(this, name); // ๋ถ๋ชจ ์์ฑ์ ํธ์ถ this.breed = breed; } // ์์ ์์ฑ์ ํจ์๊ฐ ๋ถ๋ชจ ์์ฑ์ ํจ์์ ํ๋กํ ํ์ ์ฒด์ธ์ ์์ Dog.prototype = Object.create(Animal.prototype); // ์์ ์์ฑ์ ํจ์์ ์ถ๊ฐ๋ ๋ฉ์๋ Dog.prototype.bark = function() { console.log('Woof!'); }; // ๊ฐ์ฒด ์์ฑ const dog = new Dog('Buddy', 'Golden Retriever'); // ๋ฉ์๋ ํธ์ถ dog.sayName(); // ์ถ๋ ฅ: I am Buddy dog.bark(); // ์ถ๋ ฅ: Woof!
์์ฒ๋ผ ๋ ๊ฐ์ง ํ๋กํ ํ์
์ ํฉ์ณ์ ์ฌ์ฉํ๋ ๊ฒ ๋ํ ๊ฐ๋ฅํ๋ค.
11-2-4. ํ๋กํ ํ์ ๊ฐ์ ์ํต ๊ณต์ ๋ฒ์
function Animal(name) { console.log(this.name + 'ํจ์ ์'); } // ๋ถ๋ชจ ์์ฑ์ ํจ์์ ํ๋กํ ํ์ ์ ๋ฉ์๋ ์ถ๊ฐ Animal.prototype.getName = function () { this.setName(); console.log(this.name + 'ํ๋กํ ํ์ ์'); }; Animal.prototype.setName = function () { this.name = 100; }; const myAnimal = new Animal('Fido'); myAnimal.getName(); // undefined ํจ์ ์, Fido๋ function Animal ์์ผ๋ก ๋ค์ด๊ฐ์ง ์๋๋ค. // 100 ํ๋กํ ํ์ ์, getName์ ํธ์ถ ์ Fido๊ฐ ๋ฌด์๋๊ณ 100์ด ๋ค์ด๊ฐ๋ค.
Animal์ โ์์ฑ์ ํจ์โ์ด๊ณ getName์ โํ๋กํ ํ์
โ์ ์๋ค. ๋ฐ๋ผ์, this๋ ๊ฐ๊ฐ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค. Animal ํจ์ ๋ด์์์ this๋ ์๋ก ์์ฑ๋ Animal ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๊ณ , setName ํจ์ ๋ด์์์ this๋ ๋์ผํ Animal ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํจ๋ค. getName ํจ์๋ฅผ ํธ์ถํ ๋, setName ํจ์์์ ์ค์ ๋ this.name ๊ฐ์ธ 100์ด ์ถ๋ ฅ๋๋ค.
11-3. ํ์ ์์ ํ๋กํ ํ์ ๊ณผ ์์ฑ์๋ฅผ ์ฌ์ฉ ๋ฐฉ๋ฒ
๋ค์์ ๋ฉ์๋ ์ฒด์ด๋๊ณผ ํ๋กํ ํ์
, ์๊ท๋จผํธ์ ๊ฐ์ ํ์ฉํ ์์ ์ฝ๋์ด๋ค.
function Vector(x, y) { this.x = x || 0; this.y = y || 0; } Vector.prototype = { // ์ ๋ ฅ๊ฐ์ด ํ๋์ด๋ฉด {x.x x.y} ๋ ๊ฐ์ด๋ฉด {x, y} add: function (x, y) { if (arguments.length === 1) { // ๊ฐ์ด ํ๋์ด๋ฉด ์๋ ๋ก์ง ์คํ this.x += x.x; this.y += x.y; } else if (arguments.length === 2) { // ๊ฐ์ด ๋ ๊ฐ์ด๋ฉด ์๋ ๋ก์ง ์คํ this.x += x; this.y += y; } // ๋ฉ์๋ ์ฒด์ด๋์ ์ํ ๋ฐํ๊ฐ this return this; }, sub: function (x, y) { if (arguments.length === 1) { this.x -= x.x; this.y -= x.y; } else if (arguments.length === 2) { this.x -= x; this.y -= y; } return this; }} Vector.sub = function (v1, v2) { // ์๊ท๋จผํธ๋ฅผ ๋ฐ๊ณ v1์์ v2๋ฅผ ๋นผ ๋ค์ ๋ฒกํฐ๋ฅผ ๋ง๋ ๋ค. // ํ์ง๋ง ์์ ํ๋กํ ํ์ ์ sub๋ฅผ ์ ์ํด์ ์๊ท๋จผํธ ๊ฐ์๊ฐ ํ ๊ฐ์ธ์ง ๋ ๊ฐ์ธ์ง ํ์ธํ๊ณ ์ ์ฉํ๋ค. return new Vector(v1.x - v2.x, v1.y - v2.y); }; Vector.add = function (v1, v2) { // ์์ ํ๋กํ ํ์ ์ add๋ฅผ ์ ์ํด์ ์๊ท๋จผํธ ๊ฐ์๊ฐ ํ ๊ฐ์ธ์ง ๋ ๊ฐ์ธ์ง ํ์ธํ๊ณ ์ ์ฉํ๋ค. return new Vector(v1.x + v2.x, v1.y + v2.y); }; const v1 = new Vector(3, 4); const v2 = new Vector(2, 3); const resultAdd = Vector.add(v1, v2); const resultSub = Vector.sub(v1, v2); console.log('๋ง์ ๊ฒฐ๊ณผ: (' + resultAdd.x + ', ' + resultAdd.y + ')');// ๋ง์ ๊ฒฐ๊ณผ: (5, 7) console.log('๋บ์ ๊ฒฐ๊ณผ: (' + resultSub.x + ', ' + resultSub.y + ')');// ๋บ์ ๊ฒฐ๊ณผ: (1, 1) const v3 = {x:2,y:2}; const resultOneArgAdd =v1.add(v3); console.log('์ค์นผ๋ผ ๋ง์ ๊ฒฐ๊ณผ: (' + resultOneArgAdd.x + ', ' + resultOneArgAdd.y + ')');// ์ค์นผ๋ผ ๋ง์ ๊ฒฐ๊ณผ: (5, 6) const resultOneArgSub = v1.sub(v3); console.log('์ค์นผ๋ผ ๋บ์ ๊ฒฐ๊ณผ: (' + resultOneArgSub.x + ', ' + resultOneArgSub.y + ')');// ์ค์นผ๋ผ ๋บ์ ๊ฒฐ๊ณผ: (3, 4) const v4 = new Vector(2, 3); // ๋ฉ์๋ ์ฒด์ด๋ v4.add(1, 2).sub(2, 1); console.log(v4)// { x: 1, y: 4 }
๋ฐฑ์๋ ๊ธฐ์ค์์๋ ๋ค์ํ ๋์์ธ ํจํด๊ณผ ํจ๊ป ์ฌ์ฉํ์ง๋ง ์ ํ๋ก๊ทธ๋จ์ ํ๋ก ํธ์๋์์๋ ์บ๋ฒ์ค ๋ฑ์ ์ฌ์ฉํ๋ ๋ก์ง์ด๋ค.
this.x += x; this.y += y;
์ ๋ก์ง์ผ๋ก ๊ฐ๊ฐ์ this์ ์๋ x์ y๋ฅผ ์ฆ๊ฐ์ํจ๋ค.
Vector.prototype = { add: function (x, y) { if (arguments.length === 1) { this.x += x.x; this.y += x.y; } else if (arguments.length === 2) { this.x += x; this.y += y; } return this; },
๋ง์ง๋ง์ผ๋ก ๋ฉ์๋ ์ฒด์ด๋์ ๋ฉ์๋๋ฅผ ํธ์ถํ ํ์๋ ๋ฉ์๋๋ฅผ ๋ฐํํ์ฌ ์ฐ์์ ์ผ๋ก ํธ์ถ์ ๊ฐ๋ฅํ๊ฒ ํ๋ ํจํด์ด๋ค. ์ด ํจํด์ ๋ณดํต ๋ฉ์๋๊ฐ ์๊ธฐ ์์ ์ ๋ฐํํจ์ผ๋ก์จ ์ฒด์ด๋์ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
v4.add(1, 2).sub(2, 1);