TIL 210908 : Wanted Pre-Onboarding Week 3 - 3rd Assignment

yuza🍊·2021년 9월 8일
0
post-thumbnail

Class가 뭘까?🙄

세번째 과제를 수행할 때 다른 팀원분이 class를 사용하여 코드를 짠 것을 보고 굉장히 편리하다는 생각이 들었고, 이참에 한번 자바스크립트에서 클래스를 사용하는 법을 명확하게 알아봐야겠다는 생각을 했다.

왠지 어렵게만 느껴져서 미뤄왔던 클래스 공부, 이번 기회에 잡고 가자👊🏻

Class 정의

  • 객체 생성을 위한 템플릿이자, '특별한 함수'
class Human {

}

const kim = new Human();
console.log(kim)
// Human {}
  • class 키워드로 클래스 객체를 생성할 수 있음
  • class로 만든 Human이라는 객체가 생성됨
  class Square {
  	constructor (height, width) {
    	this.height = height;
        this.width = width;
    }
    sayHi() {
    	alert(this.name)
    }
  }
  • 이 구조가 의미하는 바는

    • Square라는 이름의 함수를 만듦. 함수의 본문은 생성자 메소드인 constructor에서 가져옴(없으면 본문이 비워진 채 함수가 생성됨).
    • sayHi와 같은 메소드는 Sqaure.prototype에 저장함.
    • new Square를 호출해서 객체를 만든 후, 객체의 메소드를 호출하면 해당 메소드를 프로토타입에서 가져옴
  • 데이터 + 그 데이터를 조작하는 코드 = 클래스

Class 선언

  • 클래스를 정의하는 방법
  • Class keyword + Class name
  • ex)
  class Square {
  	constructor (height, width) {
    	this.height = height;
        this.width = width;
    }
  }
  • 클래스 선언과 함수 선언의 차이점: 함수 선언 시 호이스팅(Hoisting)이 일어나지만, 클래스 선언은 그렇지 않음

    • 호이스팅(Hoisting): 자바스크립트 코드는 함수 안의 모든 변수를 함수 맨 꼭대기로 끌어올린 것처럼 동작함, 그 현상을 호이스팅이라고 칭함
  • 따라서, 클래스를 사용하여 객체를 만들기 위해서는 미리 클래스 선언을 해둬야 함 👉🏻 그렇지 않으면, ReferenceError 발생

Class 표현식

  • 클래스를 정의하는 또 다른 방식
// 이름을 갖지 않는 클래스
let Square = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

console.log(Square.name);
// "Square"

// 이름을 갖는 클래스
let Square = class Triangle{
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

console.log(Square.name);
// "Triangle"
  • 클래스를 동적 생성 하는 방법
function makeClass(name) {
  // 클래스 선언 및 반환
  return class {
    sayHi() {
      alert("Hello, " + name);
    };
  };
}

// 새로운 클래스를 만듦
let User = makeClass("Kim");

new User().sayHi(); // Hello, Kim

생성자와 메소드🔨

Constructor 생성자

  • 클래스로 생성된 객체를 생성 & 초기화하기 위한 특수한 메소드
  • 새로운 클래스 생성 시 가장 처음 실행됨
  • constructor를 사용하여 class 객체의 초기값을 설정할 수 있음
class Human {
	constructor (name, age) {
    	this.name = name;
        this.age = age;        
    }
}

const kim = new Human('Kim', 15);
console.log(kim)
// Human {name: 'Kim', age: 15}
  • 클래스 내에 한 개만 존재 👉🏻 그렇지 않으면 SyntaxError 발생
  • constructor는 부모 클래스의 생성자를 호출하기 위해 super 키워드 사용
class Square {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

let square = new Square("Nemo");
square.sayHi();
// "Nemo"
  • new Square("Nemo") 호출 시
    • 새로운 객체 생성됨
    • 인수와 함께 constructor 자동 실행 👉🏻 인수인 "Nemo" 곧 name이기 때문에 this.name = name 로 인해 this.name에 할당됨
  • 다음과 같은 과정을 거친 뒤, square.sayHi()와 같이 객체 메소드를 호출할 수 있음

Method 메소드

  • constructor로 설정한 초기값을 이용하여 특정 기능을 수행하는 메소드를 만들 수 있다.
class Human {
	constructor (name, age) {
    	this.name = name;
        this.age = age;        
    }
    changeName (newName) {
    	this.name = newName
    }
}

const park = new Human()
park.changeName('Park')
console.log(park.name)
// 'Park'
  • 클래스 밖에서 새로운 메소드를 생성해서 사용할 수도 있다.
class Human {
    constructor (name,age) {
        this.name = name;
        this.age = age;
    }
    changeName (newName) {
    	this.name = newName
    }
}

const kim = new Human('Kim', 24);

kim.sayHi = function () {
    return 'Hi, ' + this.name
}

console.log(kim.sayHi());
// "Hi, Kim"
  • 이렇게 외부에서 만들어서 사용하는 메소드는 새로운 객체를 만들었을 때도 사용할 수 있는 것은 아니다.
class Human {
    constructor (name,age) {
        this.name = name;
        this.age = age;
    }
    changeName (newName) {
    	this.name = newName
    }
}

const kim = new Human('Kim', 24);

kim.sayHi = function () {
    return 'Hi, ' + this.name
}

console.log(kim.sayHi());

const park = new Human('Park', 13)
console.log(park.sayHi());
// TypeError: park.sayHi is not a function

Class 상속🤱🏻

extends로 상속하기

  • 클래스를 상속하여 기존 클래스의 속성들을 사용할 수 있다.
class Human {
    constructor (name,age) {
        this.name = name;
        this.age = age;
    }
    changeName (newName) {
    	this.name = newName
    }
}

class Kid extends Human {
  saySchoolName (schoolName) {
    this.schoolName = schoolName
    return `저는 ${this.schoolName}에 다녀요.`
  }
}

const choi = new Kid()
console.log(choi.saySchoolName('oo 초등학교'))
// "저는 oo 초등학교에 다녀요."

super로 가져다 쓰기

  • 상위 클래스(부모 클래스)가 갖고 있는 메소드나 초기값을 가져다 쓸 수 있다.
    • 부모가 가진 초기값을 가져와서 세팅한 뒤, 자식 클래스 내에서만 사용할 초기값을 따로 정의할 수 있음
class Human {
    constructor (name,age) {
        this.name = name;
        this.age = age;
    }
    changeName (newName) {
    	this.name = newName
    }
}

class Kid extends Human {
  constructor(name, age, schoolName){
    super(name, age);   // 부모 클래스의 초기값 가져다 쓰기
    this.schoolName = schoolName;
  }
  
  saySchoolName () {
    return `저는 ${this.schoolName}에 다녀요.`
  }
  
  sayNewName (newName) {
    super.changeName(newName)   // 부모 클래스의 메소드 가져다 쓰기
    return `저의 새 이름은 ${this.name}입니다.`
  }
}

const choi = new Kid('Choi', 10, 'oo 초등학교')
console.log(choi.saySchoolName())
// "저는 oo 초등학교에 다녀요."
console.log(choi.sayNewName('Choi Kim Park'))
// "저의 새 이름은 Choi Kim Park입니다."

참고1

참고2

profile
say hi to the world

0개의 댓글