Classes
class: 객체 생성을 위한 템플릿
함수를 함수 표현식과 함수 선언으로 정의 가능하듯 class 문법도 표현식과 선언 두가지 방법 제공
객체생성자
함수를 통해 새로운 객체를 생성 후 그 안에 넣고싶은 값 대입 구현
function Animal(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound
this.say = function(){
console.log(this.sound);
};
}
const dog = new Animal('dog', 'doggy', 'wolf!');
const cat = new Animal('cat', 'catty', 'myao');
dog.say();
cat.say();
프로토타입
같은 객체 생성자를 사용할 때 특정 함수 또는 값을 재사용 할 수 있다.
ㅇ 객체 생성자 아래에 .prototype.[key] = {} 로 설정
function Animal(type, name, sound){
this.type = type;
this.name = name;
this.sound = sound;
}
Animal.prototype.say = function() {
console.log(this.sound);
}
dog.say();
cat.say();
상속
function Animal(type, name, sound){
this.type = type;
this.name = name;
this.sound = sound;
}
Animal.prototype.say = function() {
console.log(this.sound);
}
function Dog(name, sound){
Animal.call(this, 'dog', name, sound);
}
Dog.prototype = Animal.prototype;
function Cat(name, sound){
Animal.call(this, 'cat', name, sound);
}
Cat.prototype = Animal.prototype;
const dog = new Dog('doggy', 'wolf!');
const cat = new Cat('catty', 'myao!');
dog.say();
cat.say();
call을 호출할 때 첫번째 인자는 this, 이후는 객체생성자에서 필요로하는 파라미터를 넣는다.
prototype을 공유해야하므로 상속받은 객체 생성자 함수를 만들고 prototype값을 Animal.prototype으로 설정
----------------------------------------------
Class
ES5에는 없어서 위 코드처럼 객체 생성자를 사용해 비슷하게 구현했지만
ES6에서 추가된 문법으로 객체생성자로 구현했던 코드를 더 명확하고, 깔끔히 구현이 가능하다. 상속도 훨신 간편하다.
class Animal {
constructor(type, name, sound){
this.type = type;
this.name = name;
this.sound = sound;
}
say(){
console.log(this.sound);
}
}
const dog = new Animal('dog', 'doggy', 'wolf!');
const cat = new Animal('cat', 'catty', 'myao!');
dog.say();
cat.say();
constructor: class로 생성된 객체를 생성하고 초기화를 위한 특수 메서드, constructor를 가진 특수 메서드는 클래스 안에 한개만 존재한다.
say(): 클래스 내부의 함수, 곧 이 메서드는 만들면 자동으로 prototype으로 등록이 된다.
class extends
: 상속
class Animal {
constructor(type, name, sound){
this.type = type;
this.name = name;
this.sound = sound;
}
say(){
console.log(this.sound);
}
}
class Dog extends Animal {
constructor(name, sound){
super('dog', name, sound);
}
}
class Cat extends Animal {
constructor(name, sound){
super('cat', name, sound);
}
}
const dog = new Animal('doggy', 'wolf!');
const cat = new Animal('catty', 'myao!');
dog.say();
cat.say();
Private, Public
class Rectangle {
#height = 0;
#width;
constructor(height, width) {
this.#height = height;
this.#width = width;
}
}
#을 사용한 private객체는 외부에서 접근이 안된다.
이는 반드시 사용전에 선언되어야 한다. 값을 할당하면서 만들어 질 수 없다.
선언
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
표현식
클래스 표현식은 이름을 가질수도 않을 수도 있다. 이름을 가진 표현식의 이름은 클래스 body의 local scope에 한해 유효하다. 이는 클래스의 인스턴스 이름이 아닌 name 속성을 통해 찾을 수 있음
let Rectangle = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name);
let Rectangle = class Rectangle2 {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name);
Hoisting
함수는 정의하기 전에 호출 가능하지만, 클래스는 반드시 정의한 뒤에 사용이 가능하다.
const p = new Rectangle();
class Rectangle {}
위 코드가 에러가 나오는 이유는 호이스팅될 때 초기화 되지 않기 때문이다.
Class body, 메서드
클래스 body: {}로 묶여있는 부분, 메서드나 constructor같은 멤버를 정의할 곳
Strict mode
클래스 body는 strict mode에서 실행된다. 즉 적힌 코드는 성능향상을 위해서 더 엄격하게 문법이 적용된다. 조용히 오류가 발생할 수 있다.