Constructor, Method
더글라스 크락포드가 제시한 함수 메소드 정의 방법이다 Function의 prototype으로 메소드를 정의할 수 있도록 하여 메모리 릭이 생기는것을 방지한다 프로토타입으로 생성된 클래스의 메소드는 해당 클래스영역 내에서 모두 공유한다
1 2 3 4 Function .prototype .method = function (name, func ) { if (!this .prototype [name]) this .prototype [name] = func; }
이를 기반으로 다음과 같이 생성자를 만들 수 있다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function Person (arg ) { this .name = arg; } Person .method ("setName" , function (value ) { this .name = value; }); Person .method ("getName" , function ( ) { return this .name ; }); var me = new Person ("me" );console .log (me.getName ());
상속 프로토타입 상속 Object.create()를 풀면 다음과 같이 동작한다 인자로 들어온 오브젝트를 부모로 하는 자식객체를 생성하여 리턴한다
1 2 3 4 5 function Object_create (obj ) { function F ( ) {} F.prototype = obj; return new F (); }
또한 자식 객체는 부모 객체의 메소드를 오버라이드 할 수 있어야한다
1 2 3 4 5 function extend (obj, prop ) { if ( !prop ) { prop = obj; obj = this ; } for (var i in prop) obj[i] = prop[i]; return obj; };
위와 같은 코드에서 메소드를 재정의하고 있다!prop
의 경우는 인자가 하나만 들어오는 경우이다
클래스 기반 상속 클래스 기반 상속은 다음과 같이 이루어진다 부모와 자식 사이에 빈 인스턴스를 두고 이 빈 인스턴스가 부모와 자식을 연결한다 빈 인스턴스는 클로저로써 가비지컬렉터의 대상이 아니게된다
1 2 3 4 5 6 7 8 9 var inherit = function (Parent, Child ) { var F = function ( ) {}; return function (Parent, Child ) { F.prototype = Parent .prototype ; Child .prototype = new F (); Child .prototype .constructor = Child ; Child .super = Parent .prototype ; }; }();
캡슐화 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var Person = function (arg ) { var name = arg ? arg : undefined ; var Func = function ( ) {}; Func .prototype = { getName : function ( ) { return name; }, setName : function (arg ) { name = arg; } }; return Func ; }();
위의 코드에서 Func 객체를 리턴함으로써 Person객체의 프로토타입에 접근할 수 있게 된다 또한 클로저를 사용해 name에는 접근할 수 없게된다 하지만 주의해야할 사항에서는 반환하는 객체의 private 멤버가 객체와 같이 참조값을 가지는 멤버라면 깊은 복사 를 해주어야한다
클래스 위의 내용을 종합한 클래스의 코드는 다음과 같다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 var subClass = function ( ) { var F = function ( ) { }; function SubClass (obj ) { var parent = this === window ? Function : this ; var child = function ( ) { var _parent = child.parent ; if (_parent && _parent !== Function ) { _parent.apply (this , arguments ); } if (child.prototype ._init ) { child.prototype ._init .apply (this , arguments ); } }; F.prototype = parent.prototype ; child.prototype = new F (); child.prototype .constructor = child; child.parent = parent; child.subClass = arguments .callee ; for (var i in obj) { if (obj.hasOwnProperty (i)) { child.prototype [i] = obj[i]; } } return child (); } }();