자바스크립트는 클래스는 프로토타입을 이용하여 구현한다. ES6이후로는 class 문법이 나왔기 때문에 이를 이용하면 되지만, ES6이전은 클래스 상속 개념을 흉내내는 방식으로 구현했다. ES6이전과 이후를 비교하며 알아보고자 한다.
var Rectangle = function(width, height) {
this.width = width;
this.height = height;
}
class의 constructor
는 인자를 통해 받고 this를 통해 할당하였다. 또한, 관례적으로 생성자로 쓰일 함수의 이름은 앞을 대문자로 표시하여 일반적인 함수와 구분하였다.
const Rectangle = class {
constructor(width, height) {
this.width = width;
this.height = height;
}
}
ES6이후의 문법은 자바의 클래스 문법과 비슷하다. 자바와의 차이점은 자바스크립트의 class문법은 함수이고 이는 값으로 할당할 수 있기 때문에, 위와 같이 선언하는 것이 가능하다.
static 멤버는 static field, static method등을 의미한다.
// 스태틱 메서드
Rectangle.isRectagle = function(instance) {
return instance instanceof Rectangle && instance.width > 0 && instance.height > 0;
};
Rectangle.typeName= "사각형";
var rect1 = new Rectangle(3,4);
console.log(Rectangle.isRectagle(rect1)); // true
console.log(Rectangle.typeName); // 사각형
static 멤버는 생성자에 직접 member를 할당하여 만든다.
const Rectangle = class {
static typeName = "사각형";
constructor(width, height) {
this.width = width;
this.height = height;
}
static isRectangle(rect) {
return instance instanceof Rectangle && instance.width > 0 && instance.height > 0;
}
}
const rect1 = new Rectangle(3,4);
console.log(Rectangle.isRectagle(rect1)); // true
console.log(Rectangle.typeName); // 사각형
ES5까지 class가 없었기 때문에 상속 또한 존재하지 않는다. 그래서 흉내내는 것에 초점을 맞춰 구현했었다. 그 방식은 생성자의 prototype 프로퍼티에 상속할 객체를 할당하는 방법을 이용하였다.
var Grade = function() {
var args = Array.prototype.slice.call(arguments);
for (let i = 0; i < args.length; i++) {
this[i] = args[i];
}
this.length = args.length;
}
Grade.prototype = [];
var g = new Grade(100, 80)
g.push(90);
console.log(g); // Grade { 0: 100, 1: 80, 2: 90, length: 3 }
delete g.length;
g.push(70);
console.log(g); // Grade { 0: 70, 1: 80, 2: 90, length: 1 }
위의 코드 중 Grade.prototype = [];
이 부분이 배열을 상속 받는 부분이다. 이렇게 상속을 받아서 push
메소드를 사용할 수 있게 되었다. 하지만 g.length와 같이 속성을 지우게 되면 자료구조가 깨지는 문제가 발생한다. length는 어떤 객체의 프로퍼티일 뿐이기 때문에 삭제를 막을 수 없다.