07 클래스
7-1 클래스와 인스턴스의 개념 이해
- 클래스의 속성을 지니는 실존하는 개체를 일컬어 인스턴스라고 한다.
- 한 인스턴스는 하나의 클래스만을 바탕으로 만들어진다.
7-2 자바스크립트의 클래스
- 인스턴스에 상속되는지(인스턴스가 참조하는지) 여부에 따라 스태틱 멤버와 인스턴스 멤버로 나뉜다.
- 프로토타입 메서드
var Rectangle = function (width, height) {
this.width = width;
this.height = height;
};
Rectangle.prototype.getArea = function () {
return this.width * this.height;
};
Rectangle.isRectangle = function (instance) {
return instance instanceof Rectangle && instance.width > 0 && instance.height > 0;
};
var rect1 = new Rectangle(3, 4);
console.log(rect1.getArea());
console.log(rect1.isRectangle(rect1));
console.log(Rectangle.isRectangle(rect1));
7-3 클래스 상속
7-3-1 기본 구현
- ES5까지의 자바스크립트에는 클래스가 없다.
- 하위 클래스로 삼을 생성자 함수의 prototype에 상위 클래스의 인스턴스를 부여하는 것만으로도 기본적인 메서드 상속은 가능하지만 다양한 문제가 발생.
7-3-2 클래스가 구체적인 데이터를 지니지 않게 하는 방법
- 가장 간단한 방법은 일단 만든 후 프로퍼티들을 일일이 지우고 더는 새로운 프로퍼티를 추가할 수 없게 하는 것.
- 다른 방법은 SubClass의 prototype에 직접 SuperClass의 인스턴스를 할당하는 대신 아무런 프로퍼티를 생성하지 않는 빈 생성자 함수(Bridge)를 하나 더 만들어서 그 prototype이 SuperClass의 prototype을 바라보게끔 한 다음, SubClass의 prototype에는 Bridge의 인스턴스를 할당하게 하는 것이다.
var Rectangle = function (width, height) {
this.width = width;
this.height = height;
};
Rectangle.prototype.getArea = function () {
return this.width * this.height;
};
var Square = function (width) {
Rectangle.call(this, width, width);
};
var Bridge = function () {};
Bridge.prototype = Rectangle.prototype;
Square.prototype = new Bridge();
Object.freeze(Square.prototype);
- Object.create : SubClass의 prototype의
__proto__
가 SuperClass의 prototype을 바라보되 SuperClass의 인스턴스가 되지는 않으므로 위의 두 방법보다 간단하고 안전.
7-3-3 constructor 복구하기
- SubClass.prototype.constructor가 원래의 SubClass를 바라보도록 해주면 된다.
7-3-4 상위 클래스에의 접근 수단 제공
- 하위 클래스의 메서드에서 상위 클래스의 메서드 실행 결과를 바탕으로 추가적인 작업을 수행하고 싶을 때 → ‘super’를 흉내 내본다.
var extendClass = function (SuperClass, SubClass, subMethods) {
SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;
SubClass.prototype.super = function (propName) {
var self = this;
if (!propName) return function () {
SuperClass.apply(self, arguments);
};
var prop = SuperClass.prototype[propName];
if (typeof prop !== 'function') return prop;
return function () {
return prop.apply(self, arguments);
}
};
if (subMethods) {
for (var method in subMethods) {
SubClass.prototype[method] = subMethods[method];
}
}
Object.freeze(SubClass.prototype);
return SubClass;
};
var Rectangle = function (width, height) {
this.width = width;
this.height = height;
};
Rectangle.prototype.getArea = function () {
return this.width * this.height;
};
var Square = extendClass(
Rectangle,
function (width) {
this.super()(width, width);
}, {
getArea: funtion () {
console.log('size is :', this.super('getArea')());
}
}
);
var sq = new Square(10);
sq.getArea();
console.log(sq.super('getArea')());
7-4 ES6의 클래스 및 클래스 상속
var ES5 = function (name) {
this.name = name;
};
ES5.staticMethod = function () {
return this.name + ' staticMethod';
};
ES5.prototype.method = function () {
return this.name + ' method';
};
var es5Instance = new ES5('es5');
console.log(ES5.staticMethod());
console.log(es5Instance.method());
var ES6 = class {
constructor (name) {
this.name = name;
}
static staticMethod () {
return this.name + ' staticMethod';
}
method () {
return this.name + ' method';
}
};
var es6Instance = new ES6('es6');
console.log(ES6.staticMethod());
console.log(es6Instance.method());
var Rectangle = class {
constructor (width, height) {
this.width = width;
this.height = height;
}
getArea () {
return this.width * this.height;
}
};
var Square = class extends Rectangle {
constructor (width) {
super(width, width);
}
getArea () {
console.log('size is: ', super.getArea());
}
}