자바스크립트는 클래스는 프로토타입을 이용하여 구현한다. ES6이후로는 class 문법이 나왔기 때문에 이를 이용하면 되지만, ES6이전은 클래스 상속 개념을 흉내내는 방식으로 구현했다. ES6이전과 이후를 비교하며 알아보고자 한다.

생성자

ES6 이전

var Rectangle = function(width, height) {
	this.width = width;
	this.height = height;
}

class의 constructor는 인자를 통해 받고 this를 통해 할당하였다. 또한, 관례적으로 생성자로 쓰일 함수의 이름은 앞을 대문자로 표시하여 일반적인 함수와 구분하였다.

ES6 이후

const Rectangle = class {
	constructor(width, height) {
		this.width = width;
		this.height = height;
	}
}

ES6이후의 문법은 자바의 클래스 문법과 비슷하다. 자바와의 차이점은 자바스크립트의 class문법은 함수이고 이는 값으로 할당할 수 있기 때문에, 위와 같이 선언하는 것이 가능하다.

static member

static 멤버는 static field, static method등을 의미한다.

ES6 이전

// 스태틱 메서드
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를 할당하여 만든다.

ES6 이후

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는 어떤 객체의 프로퍼티일 뿐이기 때문에 삭제를 막을 수 없다.