[JS] 상속, 프로토타입(Prototype)

javaScript 기초를 탄탄하게 다져보자

Posted by lim.Chuck on December 23, 2024

[JavaScript]

기초

  1. [JS] Js기초
  2. [JS] Js기초 변수
  3. [JS] Js기초 자료형
  4. [JS] Js기초 형변환
  5. [JS] Js기초 연산자
  6. [JS] Js기초 반복문
  7. [JS] Js기초 switch
  8. [JS] Js기초 function
  9. [JS] Js기초 객체
  10. [JS] Js기초 배열

중급

  1. [JS] Js중급 호이스팅(Hoisting)과 TDZ(Temporal Dead Zone)
  2. [JS] Js중급 생성자함수
  3. [JS] 객체 메소드(Object methods), 계산된 프로퍼티(Computed property)
  4. [JS] 심볼(Symbol)
  5. [JS] WeakMap WeakSet
  6. [JS] 숫자, 수학 method (Number, Math)
  7. [JS] 문자열 메소드(String methods)
  8. [JS] 배열 메소드(Array methods)
  9. [JS] 구조 분해 할당 (Destructuring assignment)
  10. [JS] 매개변수 리스트와 전개 문법(Rest parameters and spread syntax)
  11. [JS] 클로저(Closure)
  12. [JS] setTimeout / setInterval
  13. [JS] call / apply / bind
  14. [JS] 상속, 프로토타입(Prototype)
  15. [JS] 클래스(Class)
  16. [JS] 클로미스(Promise)
  17. [JS] 비동기 처리(Async/Await)
  18. [JS] Generator
  19. [JS] 메모리 릭(Memory Leak)

자바스크립트의 상속과 프로토타입! 객체 지향 프로그래밍의 핵심이야! 🔗

1. 프로토타입 기본

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 프로토타입 체인 기본
const animal = {
  eat: function () {
    console.log("먹는다");
  },
};

const dog = {
  bark: function () {
    console.log("멍멍!");
  },
};

// dog의 프로토타입을 animal로 설정
Object.setPrototypeOf(dog, animal);
// 또는
// dog.__proto__ = animal;

dog.bark(); // "멍멍!"
dog.eat(); // "먹는다"

2. 생성자 함수와 프로토타입

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 생성자 함수
function Animal(name) {
  this.name = name;
}

// 프로토타입에 메서드 추가
Animal.prototype.eat = function () {
  console.log(`${this.name}이(가) 먹는다`);
};

function Dog(name, breed) {
  // Animal 생성자 호출
  Animal.call(this, name);
  this.breed = breed;
}

// Dog 프로토타입을 Animal 프로토타입을 상속받도록 설정
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// Dog 프로토타입에 메서드 추가
Dog.prototype.bark = function () {
  console.log("멍멍!");
};

const myDog = new Dog("멍멍이", "진돗개");
myDog.eat(); // "멍멍이이(가) 먹는다"
myDog.bark(); // "멍멍!"

3. 클래스를 사용한 상속 (ES6+)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Animal {
  constructor(name) {
    this.name = name;
  }

  eat() {
    console.log(`${this.name}이(가) 먹는다`);
  }

  sleep() {
    console.log(`${this.name}이(가) 잔다`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // 부모 클래스 생성자 호출
    this.breed = breed;
  }

  bark() {
    console.log("멍멍!");
  }

  // 메서드 오버라이딩
  eat() {
    super.eat(); // 부모 메서드 호출
    console.log("사료를 먹는다");
  }
}

const myDog = new Dog("멍멍이", "진돗개");
myDog.eat();
// "멍멍이이(가) 먹는다"
// "사료를 먹는다"
myDog.bark(); // "멍멍!"

4. 다중 상속과 믹스인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 믹스인 함수
const swimMixin = {
  swim() {
    console.log(`${this.name}이(가) 수영한다`);
  },
};

const flyMixin = {
  fly() {
    console.log(`${this.name}이(가) 날아간다`);
  },
};

class Bird extends Animal {
  constructor(name) {
    super(name);
    // 믹스인 적용
    Object.assign(this, flyMixin);
  }
}

class Duck extends Bird {
  constructor(name) {
    super(name);
    // 여러 믹스인 적용
    Object.assign(this, swimMixin);
  }
}

const duck = new Duck("도널드");
duck.eat(); // "도널드이(가) 먹는다"
duck.fly(); // "도널드이(가) 날아간다"
duck.swim(); // "도널드이(가) 수영한다"

5. 프로토타입 체인 탐색과 속성 검색

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Vehicle {
  constructor(type) {
    this.type = type;
  }

  getType() {
    return this.type;
  }
}

class Car extends Vehicle {
  constructor(type, brand) {
    super(type);
    this.brand = brand;
  }
}

const myCar = new Car("sedan", "Toyota");

// 프로토타입 체인 확인
console.log(myCar.__proto__ === Car.prototype); // true
console.log(Car.prototype.__proto__ === Vehicle.prototype); // true
console.log(Vehicle.prototype.__proto__ === Object.prototype); // true

// 속성 존재 확인
console.log(myCar.hasOwnProperty("brand")); // true
console.log(myCar.hasOwnProperty("type")); // true
console.log(myCar.hasOwnProperty("getType")); // false

6. 실전 예제: 컴포넌트 상속

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Component {
  constructor(name) {
    this.name = name;
    this.state = {};
  }

  setState(newState) {
    this.state = { ...this.state, ...newState };
    this.render();
  }

  render() {
    throw new Error("render 메서드를 구현해야 합니다");
  }
}

class Button extends Component {
  constructor(name) {
    super(name);
    this.state = { clicked: false };
  }

  click() {
    this.setState({ clicked: true });
  }

  render() {
    console.log(
      `Button ${this.name} is ${this.state.clicked ? "clicked" : "not clicked"}`
    );
  }
}

const myButton = new Button("Submit");
myButton.render(); // "Button Submit is not clicked"
myButton.click(); // "Button Submit is clicked"

꿀팁! 🍯

  1. 프로토타입 체인 최적화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// BAD: 인스턴스마다 메서드 생성
class BadExample {
  constructor() {
    this.method = function () {
      console.log("비효율적");
    };
  }
}

// GOOD: 프로토타입에 메서드 정의
class GoodExample {
  method() {
    console.log("효율적");
  }
}
  1. instanceof vs isPrototypeOf
1
2
3
4
5
6
7
8
9
10
11
12
class Animal {}
class Dog extends Animal {}

const dog = new Dog();

// instanceof: 생성자 함수 확인
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true

// isPrototypeOf: 프로토타입 체인 확인
console.log(Dog.prototype.isPrototypeOf(dog)); // true
console.log(Animal.prototype.isPrototypeOf(dog)); // true

이제 상속과 프로토타입은 마스터! 😎 객체 지향 프로그래밍을 자유자재로 할 수 있을 거야!