Class와 상속(inheritance)

Ming·2023년 9월 21일

JavaScript

목록 보기
13/15

생성자 함수(constructor function)

: 유사한 객체를 여러개 만들 수 있는 생성자 함수 = Object 생성기계!
: 생성자 함수로 생성되는 오브젝트는 인스턴스라고 한다!

생성자 함수를 만들기 위해서는

    1. 반드시 'new' 연산자를 붙여햐 한다.
    1. 함수 이름은 첫 글자는 대문자여야 한다.

예제

function User(name,age){
  this.name = 'name';
  this.sayHi = function(){
    console.log('안녕하세요' + this.name + ' 입니다');
  }

let user1 = new User('kim');
user1.sayHi() // 안녕하세요 kim 입니다
let user2 = new User('park')
user2.sayHi() // 안녕하세요 park 입니다

알고리즘
빈 객체를 만들어 this 할당 -> this에 새로운 프로퍼티를 추가해 this 수정 -> this 반환
= this는 새로 생성되는 오브젝트!


Prototype

: 자바스크립트 객체가 갖는 숨겨져 있는 프로퍼티 값 = 부모의 유전자역활!
위에 constructor가 가진 name 속성을 그대로 물려받아 오브젝트를 하나 생성했다.
이런 과정을 상속이라고 한다.
User함수는 부모 user1, user2는 자식이라고 비유한다.

예제

function User(){
  this.name = 'Kim';
}
User.prototype.age = '15';

let user1 = new User();
console.log(user1.age); // 15
console.log(user1); // User(){this.name = 'Kim';}

부모 prototype 변수나 함수가 있으면 생성되는 자식들은 상속받아 그래도 사용할 수 있다!

🫡 근데 왜 가능할까...?
object에서 속성을 읽으려고 하는데 해당 속성이 없으면 자동으로 프로토타입에서 속성을 찾기 때문에
= 본인에게 없으면 부모에게 물어본다!

constructor 상속과 prototype 상속 차이

constructor: 자식들이 값을 직접 상속받아 소유
prototype: 부모만 가지고 있고 참조해서 사용
자식들이 직접 값을 가지게 만들고 싶으면 constructor로 만들고, 부모만 가지고 있고 참조해서 쓰고 싶으면 prototype으로 만들면 된다.
보통은 상속할 수 있는 함수 같은 것들은 prototype으로 많이 만들어놓는다.

Prototype의 특징

  • prototype은 constructor 함수에만 몰래 생성된다.
    일반 object, array 만들면 없다.
    근데 상속하고 싶으면...? Object.create() 또는 Class를 쓰거나 constructor를 쓰거나 3중 하나!

  • 부모의 prototype을 찾고 싶으면 __proto__ 사용
    부모로부터 생성된 자식 Object들은 __proto__라는 속성이 있다.

function 기계(){
  this.name = 'Kim';
  this.age = 15;
}
var 학생1 = new 기계();
console.log(학생1.__proto__);
console.log(기계.prototype);
// 결과적으로 같은 의미를 가진다.

  • __proto__를 직접 등록하면 object끼리 상속기능을 구현가능하다.
    __proto__는 부모의 prototype을 의미한다.
    그럼 어떤 object에다가 __proto__를 강제로 하나 설정해버리면 어떻게 될까? -> 부모님이 생겨버린다.
var 부모 = { name : 'Kim' };
var 자식 = {};

자식.__proto__ = 부모;
console.log(자식.name); // kim

Class

👀 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀
ES6에 추가된 class는 유사한 객체를 여러개 만들 수 있다.(constructor 만들기)

예제

  1. 함수를 constructor 안에 추가하는 방법
class User {
  constructor(name){
    this.name = name;
    this.sayHi = function(){
    console.log('안녕하세요' + this.name + ' 입니다');}
  }
}

let user1 = new User('min') // 새로 생성된 자식은 sayHi함수를 직접 가지게 된다
user1.sayHi()
  1. 함수를 prototype에 추가하는 방법
class User {
  constructor(name){
    this.name = name;
  }
  sayHi = function(){ // 부모의 prototype에 추가됨
    console.log('안녕하세요' + this.name + ' 입니다');
  }
}

let user1 = new User('min')// 새로 생성된 자식은 sayHi함수를 참조받아 사용할 수 있게 된다
user1.sayHi()

extends / super

extends: 다른 클래스를 해당 클래스의 자식으로 만든다고 선언
super: 부모 속성에 접근하기 위해 사용

class A {
  constructor(){
  }
}

class B extends A{ // B를 A의 자식으로 만든다고 선언
  constructor(){
    super() // A의 [[Prototype]]
  }
}

const a = new A() // 변수 a 인스턴스 만들기
const b = new B()

console.log(a instanceof A); // true
console.log(b instanceof A); // true A를 상속받기 때문에
console.log(a instanceof B); // false

getter/setter

: 오브젝트 내의 함수들을 괄호없이 쓸 수 있게 만들어주는 키워드 => 데이터의 무결성을 보존하기 위해 쓰는 키워드!

  • set : 함수 앞에 붙이면 괄호없이 함수를 수정할 수 있다.
    데이터를 수정하는 함수라 파라미터값이 꼭 1개여야 한다.
  • get : 함수 앞에 붙이면 괄호없이 함수를 사용할 수 있다.
    데이터를 꺼내오는 함수라 return 필수로 있어야 한다.
  • setter : set이 붙은 함수
  • getter : get이 붙은 함수

사람 나이가 담긴 오브젝트가 있다. 이때 내년 나이를 출력해주는 함수를 만들어야 한다면?

let 사람 = {
  age : 30,
  nextAge(){
    return this.age+1
  }
}
사람.nextAge() // 31

🤫 사람.age+1 을 하면 쉬운데 굳이 nextAge를 왜 만들었어?

  • object 안의 데이터가 복잡할 수록 함수 만들어놓는게 데이터 꺼내기 쉽다.
  • 내부에 있는 name, age 변수를 건드리지 않아서 실수를 방지할 수 있어서 안전하다.
var 사람 = {
  age : 30,
  setAge(나이){
    this.age = 나이
  }
}

사람.setAge(20) // age:20으로 수정된다.
var 사람 = {
  age : 30,
  set setAge(나이){
    this.age = 나이
  }
  get nextAge(){
    return this.age+1
  }
}

사람.setAge=20 // age:20으로 수정된다
사람.nextAge; // 괄호없이 21로 꺼내올수있음

0개의 댓글