오늘 배운 것
클래스
클래스를 new 연산자 없이 호출하면 에러가 발행한다. → [[Call]]
이 없으며 [[Constructor]]
만 존재한다.
클래스 내부에는 메서드 축약 표현만 들어갈 수 있다.
클래스 정의
1 | // 익명 클래스 표현식 |
일반적이지는 않지만 함수와 마찬가지로 표현식으로 클래스를 정의할 수도 있다.
클래스 몸체 안에는 constructor, 프로토타입 메서드, 정적 메서드만 올 수 있다.
클래스 몸체의 constructor는 prototype의 constructor와는 다르다.
클래스 몸체의 constructor는 함수 객체의 몸체로 들어가며 없어진다.
클래스 필드 정의 제안
클래스 필드는 아래와 같다.
1 | class Foo { |
클래스 필드는 아래와 같이 인수 전달이 필요할 때 불가능하다.
1 | class Foo { |
클래스 필드에 함수를 할당하는 경우, 이 함수는 프로토타입 메서드가 아닌 인스턴스 메서드가 된며 상위 스코프는 constructor 내부이다.
1 | class Foo { |
클래스 필드는 고정값을 가지고 있을 때는 의미가 있지만 외부에서 인수를 받아 할당할 때는 constructor() 사용을 해야한다.
private 필드 정의 제안
생김새가 못 생겼지만 private 가능하다. 또한, 아직까지 유일한 private 정의 방법이다.
1 | class Person { |
private 키워드를 안 쓴 것에는 분명 이유가 있겠지만 생김새가 아쉽다.
super 키워드
1 | // 수퍼클래스 |
수퍼클래스에서 추가한 프로퍼티와 서브클래스에서 추가한 프로퍼티를 갖는 인스턴스를 생성한다면 서브클래스의 constructor를 생략할 수 없다. 이때 new 연산자와 함께 서브클래스를 호출하면서 전달한 인수 중에서 수퍼클래스의 constructor에 전달할 필요가 있는 인수는 서브클래스의 constructor에서 호출하는 super를 통해 전달한다.
1 | // 수퍼클래스 |
서브클래스에서 constructor를 생략하지 않는 경우 서브클래스의 constructor에서는 반드시 super를 호출해야 한다.
서브클래스의 constructor에서 super를 호출하기 전에는 this를 참조할 수 없다.
super는 반드시 서브클래스의 constructor에서만 호출한다. 서브클래스가 아닌 클래스의 constructor나 함수에서 super를 호출하면 에러가 발생한다. (객체 리터럴과 클래스에서만 가능)
1
2
3
4
5
6
7
8
9class Base {
constructor() {
super(); // SyntaxError: 'super' keyword unexpected here
}
}
function Foo() {
super(); // SyntaxError: 'super' keyword unexpected here
}
상속 클래스의 인스턴스 생성 과정
1 | // 수퍼클래스 |
Q. 클래스 상속이 깊어질 수록 매개변수가 많아지는게 필연적일 것 같은데 그럴 경우 대안 대책이 있는가?
A. 매개변수 많아지는게 필연적은 아니지만 만약에 그렇다면 객체 리터럴로 지정하면 될 것 같다.
ES6 함수의 추가 기능
화살표 함수
1 | // ES5 |
화살표 함수는 일반 함수 리터럴과 다르게 프로토타입 등을 만들지 않기 때문에 가볍고 가독성 또한 좋다.
화살표 함수와 일반 함수의 차이
화살표 함수는 인스턴스를 생성할 수 없는 non-constructor다.
중복된 매개변수 이름을 선언할 수 없다.
화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않는다.
위의 것을 갖지 않는다는 것은 렉시컬 환경에 위의 것이 없다는 것이다. → 상위 스코프에서 찾아야한다. → 생성자 함수, 메서드로 상용하지말고 일반적인 함수로 사용하자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Prefixer {
constructor(prefix) {
this.prefix = prefix;
}
add(arr) {
console.log(this); // Prefixer { prefix: '-webkit-' }
return arr.map((item) => this.prefix + item); //여기서 this는 화살표 함수의 상위 스코프(add 메서드)의 this
}
}
const prefixer = new Prefixer("-webkit-");
console.log(prefixer.add(["transition", "user-select"]));
// ['-webkit-transition', '-webkit-user-select']