[백업][가리사니] javascript class
javascript

이 문서는 가리사니 개발자 포럼에 올렸던 글의 백업 파일입니다. 오래된 문서가 많아 현재 상황과 맞지 않을 수 있습니다.

이 문서는 ECMAScript 6 추가 기능을 서술하고 있습니다.

모질라 문서

참고사항

일반적인 클래스와 상속

// class 이름
class Saro
{
	// 생성자
	constructor()
	{
		console.log('사로 생성자');
		// 프로토타입 생성자함수 처럼 동적 this 로 사용.
		this.host = 'saro.me';
	}

	// === 함수 / 함수 제네레이터와 / 프로퍼티
	// === 이 3가지는 ES 6에서 굳이 클래스가 아니더라도 이렇게 표현할 수 있는 식이 추가됨.
	// === 위 참고사항의 : ES 6 추가기능 참고.
	// 제네레이터 펑션  : 여기서 다루지 않음 : 위 참고사항 참고
	* genFunc() { /* ... */ }
	// get set 프로퍼티 : 여기서는 사용만함, 설명은 위 참고사항.
	get propertyValue()
	{
		return '호스트 : ' + this.host;
	}
	set propertyValue(host)
	{
		console.log('호스트는 바꿀수 없습니다.');
	}
	// 함수 표현
	getHost()
	{
		return this.host;
	}

	// 아래에서 상속받았을때 실험.
	getThis()
	{
		return this;
	}

	// 스테틱 함수의 경우 이렇게 사용한다.
	static staticFunction()
	{
		console.log('스테틱 함수입니다.');
	}

	out()
	{
		console.log('사로 : ' + this.host);
	}
};

// class 이름 extends 상속 : 많은 언어들의 상속과 같은 문법.
class Garisani extends Saro
{
	// 생성자
	constructor()
	{
		// 생성자의 super 는 this 가 불리기 전에 해야한다.
		super();
		console.log('가리사니 생성자');
		this.host = 'gs.saro.me';
	}

	// out 오버라이드
	// param을 쓴 이유는 인자의 길이가 동적인 자바스크립트엔
	// 오버로딩이 없다는 것을 설명하기 위함.
	out(param)
	{
		console.log('가리사니 : ' + this.host);
		console.log('상위 메서드를 불러볼까?');
		// 일반적으로도 수퍼를 사용할 수 있다.
		super.out();
	}
};

console.log('Saro 생성준비');
var saro = new Saro();
console.log('Garisani생성준비');

// super 가 불려서 saro의 생성자가 작동한 것을 볼 수 있다.
var gs = new Garisani();
console.log('모두 생성 완료');

// 출력
saro.out();
// gs.out 생성을 보면 자스엔 오버로딩이 없다는걸 보여주기위함.
// 여기서는 파라미터를 쓰지않았지만 자스에선 파라미터가 arguments 개념이다.
gs.out();

// 당연하지만 자바스크립트 상속은 스테틱도 상속한다.
Garisani .staticFunction();

console.log(' 클래스의 이름 : 덮어쓰기를   없다.');
console.log(Saro.name);
console.log(Garisani.name);

console.log('프로퍼티 기능');
console.log(saro.propertyValue);
console.log(gs.propertyValue);
gs.propertyValue = "123"; // 입력불가
console.log(gs.propertyValue);

console.log('this  리턴하는 함수를 상속 받으면 this  자동치환된다.');
gs.getThis().out();

실행결과 뭔가 이상한 점들을 발견하지 않았는가?

부모객체와 맴버변수를 공유한다.

  • 보통 언어에선 부모와 맴버변수를 공유하지 않는다.
  • 잘 생각해보면 자바스크립트는 var 가 만능자료형이다. 맴버변수를 공유하다보니 낯선 결과가 보인다.
  • gs.out(); 실행부분을 보자 super.out(); 이 공유된 맴버번수 host를.. 부르는 특이함을 볼 수 있다...
  • 마찬가지로 get set 프로퍼티도 공유된 결과를 보인다. 오버라이딩은 되지만 오버로딩은 되지 않는다.
  • 자스에선 파라미터가 arguments 개념이다.
  • 즉, 파라미터가 달라져도 함수 이름으로만 부르며, 이 특성은 클래스에서도 달라지지 않는다. 접근자 설정이 없다.
  • 위 예제를 보면 클래스가 아닌 프로토타입의 확장처럼 느껴진다.
  • 추가 : 어떤 분께서 언어에 따라 클래스에 접근자가 기능이 없는 경우도 있다고한다. - 자스의 특징이 아님.

그렇다면 프로토타입 처럼 함수만 호출하면 따로 바인딩을 해줘야하나?

  • 바로 위 설명처럼 자바스크립트는 함수나 변수가, 다 같은 변수특성을 갖는다.
// gs.saro.me
console.log(gs.getHost());

var isMethod = gs.getHost;
// 오류발생 : 그냥 프로토타입처럼 함수만 떨어져나왔다..
console.log(isMethod());

그렇다.. 프로토타입과 동일 특성을 갖는다..

var temp;
// 성공 - gs.saro.me
temp = gs.getHost
console.log(temp.bind(gs)());

// 성공 - saro.me
temp = gs.getHost
console.log(temp.bind(saro)());

// 동적으로
temp = gs.getHost
console.log(temp.bind({ host : '동적값을 넣어보았다.' })());

saro 를 넣어도 성공한다.. 메서드라기보단 함수이다. 즉, 함수를 인자로 전달할대는 바인드 방식을 그대로 이용해야한다.

그럼 동적 프로토타입도 그대로 작동할까?

Saro.prototype.out = function()
{
	console.log('사로 클래스의 out을 프로토타입으로 덮어버림');
};

// 출력
saro.out();
gs.out();

결과 사로 클래스의 out을 프로토타입으로 덮어버림 가리사니 : gs.saro.me 상위 메서드를 불러볼까? 사로 클래스의 out을 프로토타입으로 덮어버림 충격과 공포....

  • 선언된 클래스의 함수(이제 메서드라고 부르긴...)도 프로토타입을 통해서 동적으로 덮을 수 있다.

분석

  • 프로토타입을 기반으로 만들어진 클래스 유사한 것 같다.
  • 상속을 받고 super 로 상위 클래스에 접근 할 수 있다는 점이 프로토타입과의 다른 특징.

익명 클래스, 지역 클래스 생성방법

윗 부분에 있어야할 거같지만, 혼란스러움을 피하기 위해 여기에 작성되었다.

var namespace = {};

// 이런식으로 변수 내부에 클래스를 만들 수 있다.
// 이때보면 class의 이름이 생략된 것을 볼 수 있다.
// 이렇게 이름이 생략된 클래스를 익명 클래스 라고한다.
namespace.ClassA = class
{
}

// 똑같이 변수에 넣지만 이번엔 이름이 있는 클래스를 만들어보았다.
namespace.ClassB = class ClassNameIsB
{
}

// 그렇다면 클래스 이름은?
// 좀전에 만든 클래스의 이름들과 같이보자.
console.log(Saro.name); // "Saro"
console.log(Garisani.name); // "Garisani"
console.log(namespace.ClassA.name); // ""
console.log(namespace.ClassB.name); // "ClassNameIsB"