2007년 11월 22일 목요일

JavaScript의 객체지향

JavaScript는 단순한 스크립트이지만 객체지향을 지원하고 있습니다.

가령 ClassA와 ClassB가 존재하고 ClassB가 ClassA를 상속하고 있다면 실제 JS로 어떻게 구현할가요?
아래에 그럼 간단한 샘플 코드를 첨부하도록 하겠습니다.

<script>
function ClassA()
{
    this.a='a';
}
function ClassB()
{
    this.b='b';
}
ClassB.prototype=new ClassA();
var objB=new ClassB();
for(var p in objB)document.write(p+"<br>");
</script>

하지만 JS의 원형 상속구조는 Clone(복사) 상속구조가 아닌 Refer(참조)상속입니다.
이런 이유땜에 만약 ClassA인스턴스 맴버변수를 변경하면 ClassB 인스턴스도 변화를 가져오게 됩니다.

<script>
function ClassA()
{
    this.a='a';
}
function ClassB()
{
    this.b='b';
}
ClassB.prototype=new ClassA();
var objB=new ClassB();
alert(objB.a);
ClassB.prototype.a='changed!!';
alert(objB.a);
</script>

하지만 파생된 클래스에서 맴버변수에 대한 수정은 부모 클래스에는 영향을 주지 않으므로 실제 상속된것과 같은 형태로 표현이 되여집니다. 즉 쓰기 작업은 파생된 클래스에 한해서 진행이 되고 읽기는 부모 클래스( 자식 클래스에서 오버라이딩하지 않았을시)에 한해서 진행이 되여집니다.

또한 파생된 클래스 인스턴스가 하나가 아닌 두개가 존재한다면 두 인스턴스가 동일한 부모 클래스 맴버변수를 참조하게 되므로 실제 비교를 해보면 똑같은 결과가 나옴을 알수 있습니다.

<script>
function ClassA()
{
    this.a=function(){alert();};
}
function ClassB()
{
    this.b=function(){alert();};
}
ClassB.prototype=new ClassA();
var objB1=new ClassB();
var objB2=new ClassB();
alert(objB1.a==objB2.a);
alert(objB1.b==objB2.b);
</script>

아래에 첨부한 코드를 살펴보면 가장 치명적인 문제를 발견할 수 있는데, 보시다 싶이 ClassB의 인스턴스 objB1속의 맴버변수의 값만 변경하였을 뿐인데 objB2의 값까지도 변경이 되여져 있습니다.

<script>
function ClassA()
{
    this.a=[];
}
function ClassB()
{
    this.b=function(){alert();};
}
ClassB.prototype=new ClassA();
var objB1=new ClassB();
var objB2=new ClassB();
objB1.a.push(1,2,3);
alert(objB2.a);
// 모든 ClassB 인스턴스속의 a값이 모두 변화가 일어났다!!!
</script>

이러한 원인 때문에 위에서 설명드린 방식으로 상속을 구현하는것 보다는 prototype을 이용하여 상속을 구현하면 실제 저희가 원하는 결과를 얻을수 있습니다.

prototype상속은 파생된 클래스의 원형(原型)객체를 부모클래스의 한 인스턴스로 설정하여 상속을 구현하고 있습니다.

사용상 편이를 위하여 Function 객체의 한 메소드로 정의하여 사용합니다.

Function.prototype.Extends = function (parentClass)
{
  var Bs = new Function();
  Bs.prototype = parentClass.prototype;
  this.prototype = new Bs();
  this.prototype.Super = parentClass;
  this.prototype.constructor = this;
}

2007/11/17 - [분류 전체보기] - Prototype 1.5.0 API
2007/11/14 - [자바 어플리케이션/기타 프레임웍들] - JSValidate - Form Validation Library
2007/09/14 - [자바 어플리케이션/기타 프레임웍들] - Prototype 은 어떻게 DOM에 대한 확장을 하였는가?
2007/09/13 - [자바 어플리케이션/기타 프레임웍들] - prototype 1.5.1.1 Javascript 프레임웍 사용기 - 제1부
2007/02/26 - [자바 어플리케이션/기타 프레임웍들] - Prototype을 위한 퀵 가이드

댓글 없음:

댓글 쓰기