자바스크립트로 클래스 상속을 흉내내는 더그라스 크록포드가 만든 세 함수
Function.prototype.inherits : 이 함수는 간단한 단일 부모 상속을 지원한다. 이 함수에서 대부분의 코드는 어떤 객체 메서드 안에서든 this.uber('methodName')을 호출해 그 객체가 오버라이드한 부모 객체의 메서드를 호출할 수 있게 하려고 작성되었다. 오버라이드한 부모 객체의 메서드를 호출 할 수 있는 기능은 자바스크립트 상속모델에서 기본으로 지원하지 않는 기능이다.
Function.prototype.swiss : 이 함수는 .method() 함수의 고급버전으로 한 부모 객체에서 여러 메서드를 상속받는데 사용한다. 이 함수를 여러부모 객체에 대해 사용하면 다중 상속 시능을 사용하는 것과 마찬가지가 된다.
//프로토타입에 새 함수를 연결하는 간단한 헬퍼 Function.prototype.method = function(name,func){ this.prototype[name] = func; return this; } //다른 객체로부터 우아한 방식으로 함수를 상속받으면서 여전히 부모 객체의 함수를 //호출할 수 있게 해 주는 (약간 복잡한) 함수 Function.method('inherits', function(parent){ //상속 계층 안에서 얼마나 깊이 들어왔는지 추척한다. var depth = 0; //부모의 메서드를 상속 받는다. var proto = this.prototype = new parent(); //'uber'라는 privileged 함수를 만든다. //이 함수는 상속 과정에서 덮어쓴 함수를 실행할 수 있게 해 준다. this.method('uber', function(name){ var func; //실행할 함수 var ret; //함수의 반환값 var v = parent.prototype; //부모의 프로토타입 //이미 다른 'uber'함수 안이라면 if(depth){ //근원 프로토타입을 찾아 필요한 만큼 깊이 들어간다. for( var i = depth; i > o; i -= 1){ v = v.constructor.protptype; } //그리고 그 프로토타입에서 함수를 가져온다. func = v[name]; //아니면 'uber'를 처음 호출하는 상황이다. }else{ //실행할 함수를 프로토타입에서 가져온다. func = proto[name]; //함수가 이 프로토타입의 일부였다면 if(func == this[name]){ //대신 부모 프로토타입에 간다. func = v[name]; } } //상속 스택에서 얼마나 깊이 들어왔는지를 추척한다. depth += 1; //첫 번째 전달인자를 제외한 모든 전달인자를 넘기면서 함수를 호출한다. //(첫 번째 전달인자는 우리가 호출하려는 함수 이름을 담고 있다.) ret = func.apply(this, Array.prototype.slice.apply(arguments, [1])); //스택의 깊이를 변경한다. depth -= 1; //함수 호출의 결과값을 되돌려준다. return ret; }); return this; }); //parent 객체에서 new parent()를 사용해 모든 함수를 // 상속받지 않고, 오직 함수 몇개만을 상속받는 함수 Function.method('swiss', function(parent){ for(var i = 1; i < arguments.length; i+= 1){ //상속받을 메서드들을 모두 방문한다. var name = arguments[i]; //메서드를 이 객체의 프로토타입으로 가져온다. this.prototype[name] = parent.prototype[name]; } return this; });
Posted by 홍반장