πŸ“– ν”„λ‘œν† νƒ€μž… - 2

κΈ°λ‘μΌκΈ°πŸ“«Β·2021λ…„ 1μ›” 10일
2

Javascript κ°œλ…μ •λ¦¬

λͺ©λ‘ 보기
11/15

μ§€λ‚œ 첫번째 ν”„λ‘œν† νƒ€μž… ν¬μŠ€νŒ…μ—μ„œ μƒμ†μ˜ κ°œλ…κ³Ό λͺ¨λ“  객체의 ν”„λ‘œν† νƒ€μž… μ΅œμƒμœ„μ— μœ„μΉ˜ν•œ Object 객체에 λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜λ‹€.

이번 ν¬μŠ€νŒ…μ€ ν”„λ‘œν† νƒ€μž…μ„ μ΄μš©ν•œ 상속 방법과 ν”„λ‘œν† νƒ€μž… 체인에 λŒ€ν•΄ μ •λ¦¬ν•΄λ³΄μž.


상속이 ν•„μš”ν•œ 이유

상속은 νŠΉμ • 객체의 ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œλ₯Ό μžμ‹ 객체가 κ·ΈλŒ€λ‘œ μ‚¬μš©ν•  수 있게 ν•˜λŠ” κΈ°λŠ₯이닀.
μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν”„λ‘œν† νƒ€μž…μ„ 기반으둜 상속을 κ΅¬ν˜„ν•˜κ³ , 이λ₯Ό 톡해 λΆˆν•„μš”ν•œ 쀑볡을 μ œκ±°ν•œλ‹€.

μ–΄λ–€ λ°©μ‹μœΌλ‘œ 이루어 μ§€λŠ”μ§€ μ½”λ“œλ₯Ό λ³΄λ©΄μ„œ μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜μž!

// μƒμ„±μž ν•¨μˆ˜
function Circle(radius) {
  this.radius = radius;
  this.getArea = function () {
    return Math.PI * this.radius ** 2;
  };
}

// λ°˜μ§€λ¦„μ΄ 1인 동그라미
const circle1 = new Circle(1)

// λ°˜μ§€λ¦„μ΄ 2인 동그라미
const circle2 = new Circle(2)

μœ„ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ Circleμ΄λž€ μƒμ„±μž ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜κ³  Circle객체 λ‘κ°œλ₯Ό μƒμ„±ν–ˆλ‹€.
getArea λ©”μ†Œλ“œμ˜ 경우, Circle 객체λ₯Ό λ§Œλ“€λ•Œλ§ˆλ‹€ κ°œλ³„μ μœΌλ‘œ 객체 μ•ˆμ— 생성이 λ˜μ–΄ μ‘΄μž¬ν•˜κ²Œ λœλ‹€.

즉, circle1κ³Ό circle2의 getArea λ©”μ„œλ“œλŠ” λ‹€λ₯΄λ‹€!

console.log(circle1.getArea === circle2.getArea); // false

radius의 경우 각각의 객체에 따라 λ‹€λ₯Έ 값이 주어지기에 λͺ¨λ“  객체듀이 κ°€μ Έμ•Ό ν•˜μ§€λ§Œ,

method의 경우 같은 λ™μž‘μ„ μˆ˜ν–‰ν•˜κΈ° λ•Œλ¬Έμ— ν•˜λ‚˜λ§Œ μƒμ„±ν•˜κ³  κ³΅μœ ν•˜κ²Œλ” ν•΄μ„œ λΆˆν•„μš”ν•œ λ©”λͺ¨λ¦¬κ°€ λ‚­λΉ„ λ˜λŠ”κ²ƒμ„ λ§‰λŠ”κ²Œ λ°”λžŒμ§ν•˜λ‹€.


ν”„λ‘œν† νƒ€μž…μ„ μ΄μš©ν•œ 상속 μ‚¬μš©λ²•

이제 ν”„λ‘œν† νƒ€μž…μ„ μ΄μš©ν•΄ 상속을 κ΅¬ν˜„ν•΄μ„œ μœ„μ˜ μ½”λ“œλ₯Ό κ°œμ„ ν•΄λ³΄μž!

// μƒμ„±μž ν•¨μˆ˜
function Circle(radius) {
  this.radius = radius;
}

Circle.prototype.getArea = function () {
  return Math.PI * this.radius ** 2;
};

// λ°˜μ§€λ¦„μ΄ 1인 동그라미
const circle1 = new Circle(2);

// λ°˜μ§€λ¦„μ΄ 2인 동그라미
const circle2 = new Circle(4);

circle1.getArea(); // 4

circle 객체가 μ•„λ‹ˆλΌ, circle의 ν”„λ‘œν† νƒ€μž… 객체에 getArea λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•¨μœΌλ‘œμ¨, λͺ¨λ“  circle μΈμŠ€ν„΄μŠ€μ—κ²Œ getArea λ©”μ„œλ“œλ₯Ό κ³΅μœ ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆκ²Œλ” ν•œλ‹€.

console.log(circle1.getArea === circle2.getArea); // true

λ”°λΌμ„œ μƒμ„±λœ circle μΈμŠ€ν„΄μŠ€λ“€μ˜ κ°œμˆ˜μ— 상관 없이getArea λ©”μ„œλ“œλŠ” ν•˜λ‚˜λ§Œ μƒμ„±λ˜κ³ ,
μƒμ„±λœ μΈμŠ€ν„΄μŠ€λ“€μ΄ ν”„λ‘œν† νƒ€μž… 객체에 μ ‘κ·Όν•˜μ—¬ λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλ„λ‘ ν•œλ‹€!

μœ„μ˜ μ½”λ“œμ— λΉ„ν•΄μ„œ 훨씬 효율적인 μ½”λ“œκ°€ λ˜μ—ˆλ‹€.


ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°λ₯Ό κ°–λŠ” ν•¨μˆ˜ 객체

κ·Έλ ‡λ‹€λ©΄ ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°λŠ” λͺ¨λ“  객체가 κ°–λŠ” κ²ƒμΌκΉŒ? 결둠을 미리 μ–˜κΈ°ν•˜μžλ©΄ λͺ¨λ“  객체가 가지고 μžˆμ§€λŠ” μ•Šλ‹€.
λ‹€μŒ μ˜ˆμ‹œλ₯Ό 보자.

function Person(name){
  this.name = name;
}

const Person2 = name => {
  this.name = name;
}

console.log(Person.prototype); // {constructor f}
console.log(Person2.prototype); // undefined

const p1 = new Person('sihyun'); 
const p2 = new Person2('sihyun2'); // TypeError: Person2 is not a constructor

μ‹€ν–‰ κ²°κ³Όλ₯Ό 보면, μƒμ„±μžλ‘œμ„œ ν˜ΈμΆœν•  수 μžˆλŠ” Person은 prototype ν”„λ‘œνΌν‹°λ₯Ό 가지고 μžˆμ§€λ§Œ
ν™”μ‚΄ν‘œ ν•¨μˆ˜μΈ Person2λŠ” prototype ν”„λ‘œνΌν‹°λ₯Ό 가지고 μžˆμ§€ μ•Šμ€κ²ƒμ„ 확인할 수 μžˆλ‹€.

즉, μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆλŠ” μƒμ„±μž ν•¨μˆ˜λ§Œμ΄ ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°λ₯Ό κ°–λŠ”λ‹€.

ν™”μ‚΄ν‘œ ν•¨μˆ˜κ°€ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μ—†λŠ” μ΄μœ λŠ” [[Construct]]λΌλŠ” λ‚΄λΆ€ λ©”μ„œλ“œλ₯Ό 가지고 μžˆμ§€ μ•ŠκΈ° λ•Œλ¬ΈμΈλ°, ν•΄λ‹Ή λ‚΄μš©μ— λŒ€ν•΄ κΆκΈˆν•˜λ‹€λ©΄ μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•œ 객체 생성 ν¬μŠ€νŒ…μ„ μ°Έμ‘°ν•˜λ©΄ 될 것 κ°™λ‹€.


ν”„λ‘œν† νƒ€μž… 체인

그러면 상속받은 κ°μ²΄λŠ” μ–΄λ–»κ²Œ λΆ€λͺ¨μ˜ λ©”μ„œλ“œλ₯Ό 직접 μ‚¬μš©ν•  수 μžˆμ„κΉŒ?πŸ€”
이에 λŒ€ν•΄ μ΄ν•΄ν•˜λ €λ©΄ ν”„λ‘œν† νƒ€μž… 체인을 μ•Œμ•„μ•Όν•œλ‹€.

πŸ’‘ ν”„λ‘œν† νƒ€μž… μ²΄μΈμ΄λž€?

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ 객체의 ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œλ₯Ό μ°Έμ‘°ν•˜κ²Œ 되면, ν•΄λ‹Ή κ°μ²΄μ—μ„œ ν”„λ‘œνΌν‹°λ₯Ό μ°Ύμ•„λ³΄κ²Œ 되고 λ°œκ²¬ν•˜μ§€ λͺ»ν•˜λ©΄ κ·Έ ν”„λ‘œν† νƒ€μž… 객체(λΆ€λͺ¨ 객체)둜 μ΄λ™ν•˜μ—¬ ν•΄λ‹Ή ν”„λ‘œν† νƒ€μž… 객체 λ‚΄μ—μ„œ 멀버λ₯Ό μ°ΎλŠ”λ‹€.

이 과정은 멀버λ₯Ό μ°Ύκ±°λ‚˜, 멀버λ₯Ό 찾지 λͺ»ν•˜κ³  μ΅œμƒμœ„ 였브젝트인 Object의 ν”„λ‘œν† νƒ€μž… κ°μ²΄κΉŒμ§€ κ²€μƒ‰ν•˜λ©΄ λλ‚˜κ²Œ λœλ‹€.

μ΄λŸ¬ν•œ κ°μ²΄λ“€μ˜ 연쇄λ₯Ό κ°€λ¦¬μΌœ ν”„λ‘œν† νƒ€μž… 체인(prototype chain)이라고 ν•œλ‹€.

μ‰½κ²Œ λ§ν•˜λ©΄ μžμ‹κ³Ό λΆ€λͺ¨κ°μ²΄λŠ” ν”„λ‘œν† νƒ€μž… μ²΄μ΄λ‹μœΌλ‘œ μ—°κ²°λ˜μ–΄ 있고, μžμ‹ 객체에 μ—†λŠ” ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œλŠ” λΆ€λͺ¨κ°μ²΄, κ·Έ λΆ€λͺ¨κ°μ²΄μ—μ„œ κ²€μƒ‰ν•˜μ—¬ μ‚¬μš©ν•œλ‹€λŠ” 이야기이닀!

자, 그러면 예제λ₯Ό ν†΅ν•΄μ„œ ν”„λ‘œν† νƒ€μž… 체인을 κ²€μƒ‰ν•˜λŠ” 과정을 μ΄ν•΄ν•΄λ³΄μž.

// μƒμ„±μž ν•¨μˆ˜
function Person(name) {
  this.name = name;
}

let foo = new Person('Lee');

Person.prototype.sayHello = function(){
  console.log('Hi! my name is ' + this.name);
};

foo.sayHello();

μƒμ„±λœ foo κ°μ²΄μ—μ„œ sayHello λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ²Œ 되면, 일단 ν•΄λ‹Ή foo 객체 μ•ˆμ—μ„œ sayHello λ©”μ„œλ“œλ₯Ό μ°ΎλŠ”λ‹€.

κ·Έ 이후 검색에 μ‹€νŒ¨ν•˜λ©΄, ν•΄λ‹Ή 객체의 λΆ€λͺ¨κ°μ²΄μΈ Person.prototype 객체에 μ ‘κ·Όν•΄μ„œ sayHello λ©”μ„œλ“œλ₯Ό μ°Ύκ³ , 검색에 μ„±κ³΅ν•˜μ—¬ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ²Œ λ˜λŠ” 것이닀!

즉, μ•„λž˜μ™€ 같은 ꡬ쑰둜 ν”„λ‘œν† νƒ€μž… 체이닝이 ν˜•μ„±λœλ‹€.

이미지 좜처 : https://poiemaweb.com/js-prototype

μ΄λ ‡κ²Œ ν”„λ‘œν† νƒ€μž… 체인이 μ—°κ²°λ˜μ–΄ 있기 λ•Œλ¬Έμ—, foo κ°μ²΄λŠ” λΆ€λͺ¨ 객체인 Person.prototype κ°μ²΄μ—μ„œ sayHello λ©”μ„œλ“œλ₯Ό μ°Ύμ•„μ„œ μ΄μš©ν•  수 μžˆλŠ” 것이닀!


마치며

μ§€κΈˆκΉŒμ§€ 두 νŽΈμ— κ±Έμ³μ„œ ν”„λ‘œν† νƒ€μž…μ— λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜λ‹€! πŸ‘πŸ‘πŸ‘

constructor와 Object.create ν•¨μˆ˜μ— λŒ€ν•΄μ„œλ„ λ‹€λ€„λ³ΌκΉŒ ν–ˆλŠ”λ°, ν¬μŠ€νŒ… λ‚΄μš©μ΄ λ„ˆλ¬΄ κΈΈμ–΄μ§ˆ 것 κ°™μ•„ μƒλž΅ν•˜μ˜€λ‹€.

사싀 μ €λ²ˆμ£Όμ— μ™„μ„±ν•˜λ €κ³  ν–ˆλ˜ ν¬μŠ€νŒ…μΈλ° 이것 저것 μ§„ν–‰ν•˜λŠ”κ²Œ λ§Žλ‹€λ³΄λ‹ˆ 쑰금 λŠ¦μΆ°μ‘Œλ‹€.
μ΅œκ·Όμ— 집쀑λ ₯이 쑰금 떨어진 것 같은데, 쑰금 더 νž˜λ‚΄μ„œ 해봐야겠닀!πŸ’ͺπŸ’ͺ

0개의 λŒ“κΈ€