Core Javascript 07 클래스

Rachel·2022년 1월 28일
0

Core Javascript

목록 보기
7/8
post-thumbnail

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()); // 12 (O)
console.log(rect1.isRectangle(rect1)); // Error (X)
console.log(Rectangle.isRectangle(rect1)); // true

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(); // size is : 100
console.log(sq.super('getArea')()); // 100

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()); // es5 staticMethod
console.log(es5Instance.method()); // es5 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()); // es6 staticMethod
console.log(es6Instance.method()); // es6 method
  • es6의 클래스 상속
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());
  }
}
profile
Frontend Developer

0개의 댓글