๐ฆ [๋ฅ๋ค์ด๋ธ ์คํฐ๋] 19. ํ๋กํ ํ์
1. ํ๋กํ ํ์ ?
js ๋ ํ๋กํ ํ์ ๊ธฐ๋ฐ์ ๊ฐ์ฒด์งํฅ ๋ ฅํ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ค.
2. ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ?
Object๋ ํฌ๊ฒ ์ด๋ค ์ํ๋ฅผ ๊ฐ์ง๋ field (property)์ ํจ์์ธ method ๋ฅผ ๊ฐ์ง๋ค. Class ๋ ์ด๋ฐ Object ๋ฅผ ์์ฑํ ์ ์๋ 'ํ'์ ๊ฐ๋ ์ด๋ค. class ์ instance ๋ฅผ object ๋ผ๊ณ ํ๋ค.
2-1. SOLID ์์น
-
๋จ์ผ ์ฑ ์ ์์น (Single Responsiblity Principle)
๋ชจ๋ ํด๋์ค๋ ๊ฐ๊ฐ ํ๋์ ์ฑ ์๋ง ๊ฐ์ ธ์ผ ํ๋ค. ํด๋์ค๋ ๊ทธ ์ฑ ์์ ์์ ํ ์บก์ํํด์ผ ํจ์ ๋งํ๋ค. -
๊ฐ๋ฐฉ-ํ์ ์์น (Open Closed Principle)
ํ์ฅ์๋ ์ด๋ ค์๊ณ ์์ ์๋ ๋ซํ์๋. ๊ธฐ์กด์ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์์ผ๋ฉด์( Closed), ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋๋ก(Open) ์ค๊ณ๊ฐ ๋์ด์ผ ํ๋ค๋ ์์น์ ๋งํ๋ค. -
๋ฆฌ์ค์ฝํ ์นํ ์์น (Liskov Substitution Principle)
์์ ํด๋์ค๋ ์ธ์ ๋ ์์ ์ ๋ถ๋ชจ ํด๋์ค๋ฅผ ๋์ฒดํ ์ ์๋ค๋ ์์น์ด๋ค. ์ฆ ๋ถ๋ชจ ํด๋์ค๊ฐ ๋ค์ด๊ฐ ์๋ฆฌ์ ์์ ํด๋์ค๋ฅผ ๋ฃ์ด๋ ๊ณํ๋๋ก ์ ์๋ํด์ผ ํ๋ค. ์์ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค์ ์ฑ ์์ ๋ฌด์ํ๊ฑฐ๋ ์ฌ์ ์ํ์ง ์๊ณ ํ์ฅ๋ง ์ํํ๋๋ก ํด์ผ LSP๋ฅผ ๋ง์กฑํ๋ค. -
์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น (Interface Segregation Principle)
ํ ํด๋์ค๋ ์์ ์ด ์ฌ์ฉํ์ง์๋ ์ธํฐํ์ด์ค๋ ๊ตฌํํ์ง ๋ง์์ผ ํ๋ค. ํ๋์ ์ผ๋ฐ์ ์ธ ์ธํฐํ์ด์ค๋ณด๋ค ์ฌ๋ฌ๊ฐ์ ๊ตฌ์ฒด์ ์ธ ์ธํฐํ์ด์ค๊ฐ ๋ซ๋ค. -
์์กด ์ญ์ ์์น (Dependency Inversion Principle)
์์กด ๊ด๊ณ๋ฅผ ๋งบ์ ๋ ๋ณํํ๊ธฐ ์ฌ์ด ๊ฒ ๋๋ ์์ฃผ ๋ณํํ๋ ๊ฒ๋ณด๋ค๋ ๋ณํํ๊ธฐ ์ด๋ ค์ด ๊ฒ, ๊ฑฐ์ ๋ณํ๊ฐ ์๋ ๊ฒ์ ์์กดํ๋ผ๋ ๊ฒ์ด๋ค. ํ๋ง๋๋ก ๊ตฌ์ฒด์ ์ธ ํด๋์ค๋ณด๋ค ์ธํฐํ์ด์ค๋ ์ถ์ ํด๋์ค์ ๊ด๊ณ๋ฅผ ๋งบ์ผ๋ผ๋ ๊ฒ์ด๋ค.
2-2.์ ์ฐจ์งํฅ vs ๊ฐ์ฒด์งํฅ
์ ์ฐจ์งํฅ => ํจ์๊ฐ ์ฌ๋ฌ๊ตฐ๋ฐ ์ฝํ์๊ธฐ๋๋ฌธ์, ํ๋๋ฅผ ์ดํดํ๊ธฐ ์ํด์ ์ ์ฒด์ ์ธ ๋์๋ฐฉ์์ ๋ชจ๋ ์ดํดํด์ผํ๋ค.ํจ์ ํ๋๋ฅผ ๋ฐ๊ฟจ์๋ ์์ธกํ์ง ๋ชปํ ์ฌ์ด๋ ์ดํํธ ๋ฐ์ ๊ฐ๋ฅ์ฑ ์์. ์ ์ง๋ณด์์ ํ์ฅ์ฑ์ด ๋จ์ด์ง๋ค.
๊ฐ์ฒด์งํฅ => ๊ฐ์ฒด๋ผ๋ฆฌ ์๋ก์๋ก ์ํตํ๋๋ก ํจ. ์ฌ๋๊ณผ ๊ฐ๊น์ด ์๊ฐ. ๊ด๋ จ์๋ ์ค๋ธ์ ํธ๋ง ์์ ํ๋ฉด ๋๊ณ , ์ฌ๋ฌ๋ฒ ๋ฐ๋ณต๋๋๊ฑด ์ฌ์ฌ์ฉํ ์ ์๋ค. ์๋ก์ด ๊ธฐ๋ฅ์ด ํ์ํ๋ฉด ํ์ฅํด์ ์ฌ์ฉํ ์ ์๋ค๋ ์ฅ์ . ๋น ๋ฅด๊ฒ ์ ์ง๋ณด์๊ฐ ๊ฐ๋ฅํจ.
2-3.์์๊ณผ ํ๋กํ ํ์
์์(inheritance)์ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ ๊ฐ๋ ์ผ๋ก, ๋ถ๋ชจ ๊ฐ์ฒด์ ํ๋กํผํฐ ๋๋ ๋ฉ์๋๋ฅผ ๋ค๋ฅธ ๊ฐ์ฒด๊ฐ ์์๋ฐ์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๊ฒํ๊ณ ๊ธฐ๋ฅ์ ์ผ๋ถ๋ถ์ ๋ณ๊ฒฝํด์ผ ํ ๊ฒฝ์ฐ ์์๋ฐ์ ์์ํด๋์ค์์ ํด๋น ๊ธฐ๋ฅ๋ง ๋ค์ ์์ (์ ์)ํ์ฌ ์ฌ์ฉํ ์ ์๊ฒ ํ๋ ๊ฒ์ด๋ค. ์๋ฐ์คํฌ๋ฆฝํธ๋ ํ๋กํ ํ์ ์ ๊ธฐ๋ฐ์ผ๋ก ์์์ ๊ตฌํํ์ฌ ๋ถํ์ํ ์ค๋ณต์ ์ ๊ฑฐํ๋ค. prototype์ ์ฌ์ฉํ์ง ์์์ ๋๋ ๋์ผํ ์์ฑ์ ํจ์์ ์ํด ์์ฑ๋ ๋ชจ๋ ์ธ์คํด์ค๊ฐ ๋์ผํ ๋ฉ์๋๋ฅผ ์ค๋ณต ์์ ํ์ฌ ๋ถํ์ํ๊ฒ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ญ๋นํ๋ ์ํฉ์ด ๋ฐ์ํ์๋๋ฐ, ์ด๋ฌํ ์ค๋ณต์ prototype์ ๊ธฐ๋ฐ์ผ๋กํ ์์์ ๊ตฌํํ๋ฉด ํด๊ฒฐํ ์ ์๋ค.
const person = { name: 'Lee' };
//persone ๊ฐ์ฒด๋ __proto__ ํ๋กํผํฐ๋ฅผ ์์ ํ์ง ์๋๋ค.
console.log(person.hasOwnProperty('__proto__') //false
//๋ชจ๋ ๊ฐ์ฒด๋ Object.prototype์ ์ ๊ทผ์ ํ๋กํผํฐ __proto__๋ฅผ ์์๋ฐ์ ์ฌ์ฉํ ์ ์๋ค.
console.log({}.__proto__ === Object.prototype); //true
===========================< ๋ฌธ์ >=============================
1. __proto__
์ ๊ทผ์ ํ๋กํผํฐ๋ฅผ ํตํด ํ๋กํ ํ์
์ ์ ๊ทผํด์ผํ๋ ์ด์ ๋?
ํ๋กํ ํ์ ์ ๊ฐ๋ฆฌํค๋ [[Prototype]] ๋ด๋ถ ์ฌ๋กฏ์ ์ ๊ทผํ ์ ์๋ค. ์ด๋ ํ๋กํผํฐ๊ฐ ์๋๋ค. ๋ฐ๋ผ์, ์๋ฐ์คํฌ๋ฆฝํธ๋ ์์น์ ์ผ๋ก ๋ด๋ถ ์ฌ๋กฏ๊ณผ ๋ด๋ถ ๋ฉ์๋์ ์ง์ ์ ๊ทผํ๊ฑฐ๋ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง ์๋๋ค. ๋จ, ๊ฐ์ ์ ์ผ๋ก ๋ด๋ถ ์ฌ๋กฏ์ ๊ฐ, ์ฆ ํ๋กํ ํ์ ์ ์ ๊ทผํ ์ ์๋ค. ์ด๋ ์ํธ ์ฐธ์กฐ์ ์ํด ํ๋กํ ํ์ ์ฒด์ธ์ด ์์ฑ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด์๋ค. ํ๋กํ ํ์ ์ฒด์ธ์ ๋จ๋ฐฉํฅ ๋งํฌ๋ ๋ฆฌ์คํธ๋ก ๊ตฌํ๋์ด์ผํ๋ค. ์ฆ, ํ๋กํผํฐ ๊ฒ์ ๋ฐฉํฅ์ด ํ์ชฝ ๋ฐฉํฅ์ผ๋ก๋ง ํ๋ฌ๊ฐ์ผํ๋ค. ์๋ฌด๋ฐ ์ฒดํฌ์์ด ๋ฌด์กฐ๊ฑด์ ์ผ๋ก ํ๋กํ ํ์ ์ ๊ต์ฒดํ ์ ์๋๋ก, proto ์ ๊ทผ์ ํ๋กํผํฐ๋ฅผ ํตํด ํ๋กํ ํ์ ์ ์ ๊ทผํ๊ณ ๊ต์ฒดํ๋๋ก ๊ตฌํ๋์ด์๋ค.
์ ๊ทผ์ ํ๋กํผํฐ๋ ์์ฒด์ ์ผ๋ก ๊ฐ[[value]] ํ๋กํผํฐ๋ฅผ ๊ฐ์ง ์๊ณ , ๋ค๋ฅธ ๋ฐ์ดํฐ ํ๋กํผํฐ์ ๊ฐ์ ์ฝ๊ฑฐ๋ ์ ์ฅํ ๋ ์ฌ์ฉํ๋ ์ ๊ทผ์ ํจ์, ์ฆ get,set ํ๋กํผํฐ ์ดํธ๋ฆฌ๋ทฐํธ๋ก ๊ตฌ์ฑ๋ ํ๋กํผํฐ์ด๋ค.
2. ์๋ ์ฝ๋์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋งํ๊ณ ์ ๊ทธ๋ฐ์ง ์ด์ ๋ฅผ ์ค๋ช ํด๋ณด์์ค.
const Person = (function() {
function Person(name){
this.name = name;
}
Person.prototype = {
sayHello() {
console.log(`Hi! My name is ${this.name}`);
}
}
return Person;
}());
const me = new Person('Lee');
me.sayHello = function() {
console.log(`Hey! My name is ${this.name}`);
}
//์ด ๊ณผ์ ์์ ํ๋กํ ํ์
ํ๋กํผํฐ๊ฐ ์ธ์คํด์ค ํ๋กํผํฐ๋ก ๋ฎ์ด์๋๊ฒ์ด ์๋๋ผ, ์ธ์คํด์ค ํ๋กํผํฐ๋ก ์ถ๊ฐ๋๋ค.
//์ค๋ฒ๋ผ์ด๋ฉ.(์์๊ด๊ณ์ ์ํด ํ๋กํผํฐ๊ฐ ๊ฐ๋ ค์ง๋ ํ์์ ํ๋กํผํฐ ์๋์ ์ด๋ผ๊ณ ํ๋ค.
//ํ๋กํ ํ์
ํ๋กํผํฐ๋ฅผ ํ์ ๊ฐ์ฒด๋ฅผ ํตํด ๋ณ๊ฒฝ, ๋๋ ์ญ์ ํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ค.
//get ์ก์ธ์ค๋ ํ์ฉ๋๋, set ์ก์ธ์ค๋ ํ์ฉ๋์ง ์๋๋ค. ํ๋กํ ํ์
์ ์ง์ ์ ๊ทผํด์ผํ๋ค.
me.sayHello(); //Q1.์ถ๋ ฅ๊ฐ์?
'Hey! My name is Lee'
//์ธ์คํด์ค ๋ฉ์ธ์ง๋ฅผ ์ญ์ ํ๋ค.
delete me.sayHello;
//ํ๋กํ ํ์
๋ฉ์๋๊ฐ ํธ์ถ๋๋ค.
me.sayHello(); //Q2.์ถ๋ ฅ๊ฐ์?
'Hi! My name is Lee'
//ํ๋กํ ํ์
๋ฉ์๋๊ฐ ์ญ์ ๋๋ค.
delete me.sayHello;
me.sayHello(); //Q3.์ถ๋ ฅ๊ฐ์?
//type err =>
//delete Person.prototype.sayHello -> ์ด๋ ๊ฒ ํด์ผ ์ง์์ง!
//me.prototype ์ ์ธ์คํด์ค์์ ์ ๊ทผ ์๋จ!
//Q4.์ด์ ๋?
์ง์
3. ๊ฒฐ๊ณผ๊ฐ์ ๋ฌด์์ ๋๊น? ๊ทธ๋ฆฌ๊ณ ์?
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.getArea = function() {
return Math.PI * this.radius ** 2;
}
const Circle1 = new Circle(1);
const Circle2 = new Circle(2);
console.log(circle1.getArea === circle2.getArea); //true
4. ํ๋กํ ํ์ ๋ฉ์๋ sayHello๋ฅผ ์ง์ ๋ณ๊ฒฝํ๊ณ ,์ญ์ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํ ์ ์์๊น?
const Person = (function() {
function Person(name){
this.name = name;
}
//์์ฑ์ ํจ์์ prototype ํ๋กํผํฐ๋ฅผ ํตํด ํ๋กํ ํ์
์ ๊ต์ฒด
//prototype์ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ํ ๋นํ๋ค. ์ด๋ ํ๋กํ ํ์
์ ๊ฐ์ฒด ๋ฆฌํฐ๋ด๋ก ๊ต์ฒดํ ๊ฒ์ด๋ค.
Person.prototype = {
sayHello() {
console.log(`Hi! My name is ${this.name}`);
}
}
return Person;
}());
const me = new Person('Lee');
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฆ [๋ฅ๋ค์ด๋ธ ์คํฐ๋] 19. ํ๋กํ ํ์ ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@leejyart/๋ฅ๋ค์ด๋ธ-์คํฐ๋-23.-์คํ-์ปจํ ์คํธ-ํด๋ก์ ์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค