Prototype [펌]객체지향 자바스크립트

황제낙엽 2008.08.06 09:33 조회 수 : 20 추천:97

sitelink1  
sitelink2  
sitelink3  
sitelink4 http://1 
extra_vars4 ko 
extra_vars5 http://silverlining.tistory.com/tag/JavaScript%20Class 
extra_vars6 sitelink1 

객체 생성

모든 사용자 정의 클래스와 자바스크립트 내장 클래스는 Object 클래스를 상속한다. 
다시 말하자면 Object 클래스가 모든 클래스의 최상위 부모 클래스가 되는 것이다.
객체를 사용하는 방법은 아래와 같다.

 

·미리보기 | 소스복사·
  1. 1.   var obj = new Object();         // Object()의인스턴스사용   
  2. 2.   var obj2 = {};                  // new Object()와같다.   
  3. 3.   function MyObject(){}           // 사용자정의클래스   
  4. 4.   var obj3 = new MyObject();      // 사용자정의클래스인스턴스  

 

표 1 JavaScript의 객체 생성

 

 


사용자 정의 클래스

 

 

 

·미리보기 | 소스복사·
  1. 1.   function hello(arg1, arg2)   
  2. 2.   {   
  3. 3.       this.prop1 = arg1;   
  4. 4.       this.prop2 = arg2;   
  5. 5.       this.method1 = function()   
  6. 6.       {   
  7. 7.           this.prop1 += 2;   
  8. 8.       }   
  9. 9.       this.method2 = function()   
  10. 10.      {   
  11. 11.          alert(this.prop1);   
  12. 12.          alert(this.prop2);   
  13. 13.      }   
  14. 14.  }   
  15.   
  16. 15.  var obj = new hello(1,"hello");   
  17. 16.  obj.method2();  // 1과hello 출력   
  18. 17.  obj.method1();  // prop1 = 1+2 = 3  
  19. 18.  obj.method2();  // 3과hello 출력  

 

표 2 JavaScript의 사용자 정의 클래스 사용


위 코드에서 “function hello(){ … }”는 함수 선언이 아닌 클래스의 선언이다. 
따라서 hello는 함수가 아니라 클래스가 된다. 클래스를 인스턴스화 하는 방법은 일반적인 객체지향언어에서 처럼 new 키워드를 사용하여 “var obj = new hello();”와 같이 수행한다.
주의 해서 볼 것은 hello 클래스의 멤버 메서드 선언이다.(5번과 9번라인) 
일반적인 function method1(){…}과 같은 형식으로 변경 시 해당 메서드는 hello 객체의 내부(private) 메서드로 사용되어 외부에서 접근할 수 없다. 
this.method1 = function(){…}과 같이 선언하므로써 외부(public)에서 접근하여 사용할 수 있게 된다.



Prototype Chain

Object 클래스의 대표적인 프로퍼티중 주목할 것은 prototype 프로퍼티이다. 
다음 예제를 보면서 prototype 프로퍼티의 쓰임새를 살펴보자.

 

 

·미리보기 | 소스복사·
  1. 1.   var obj = new Object();   
  2. 2.   //obj.prototype.a = "old";  // 오류발생. 실행멈춤.   
  3. 3.   Object.prototype.a = "old";   
  4. 4.   alert(obj.a);   // "old"출력, Object.prototype.a 출력   
  5.   
  6. 5.   obj.a = "new";   
  7. 6.   alert(obj.a);   // "new"출력, 객체멤버가prototype 멤버보다우선한다.   
  8. 7.   alert(Object.a);// "old"출력. prototype 멤버(클래스멤버)가출력된다.     
  9.   
  10. 8.   function Test(){}   
  11. 9.   alert(Test.a);   // "old"출력. Object.prototype.a를사용하기때문   
  12.   
  13. 10.  Test.a = "b";   
  14. 11.  alert(Object.a); // "old"출력. Test.prototype.a와Object.prototype.a는다르다.   
  15. 12.  alert(Test.a);   // "b"출력.   
  16.   
  17. 13.  var test = new Test();   
  18. 14.  alert(test.a);  // "old"출력. test 객체에는객체멤버a가없다. 대신prototype chain에의해a를찾아출력해준다.   
  19. 15.  alert(Test.a);  // "b"출력.   
  20.   
  21. 16.  test.a = "test's old";   
  22. 17.  alert(test.a);  // "test's old" 출력   
  23.   
  24. 18.  Test.a = "test's prototype old";   
  25. 19.  alert(test.a);  // "test's old" 출력. new Test()에의해메모리에생성된test 객체와Test 클래스는변수메모리공간이다를것이다.   
  26. 20.  alert(Test.a);  // "test's prototype old"출력  

 

 

표 3 prototype 프로퍼티를 활용한 동적 멤버 추가

 


위의 예제에서 우린 prototype의 다음 특성을 알 수 있다.
1)     prototype 프로퍼티는 클래스 멤버이지 객체의 멤버가 아니다. 즉, 위 코드에서 3번라인 Object.prototype.a = “old” 를 2번 라인의 obj.prototype.a = “old”로 할 수 없다. 브라우저에서 실행시 2번라인에서 실행이 멈추는 것을 확인할 수 있었다.
2)     객체 멤버가 prototype 멤버보다 우선한다. 5번 라인의 obj.a = “new”; 에서 a멤버는 객체 obj의 멤버로 Object.prototype.a의 값은 여전히 존재하지만 객체 obj의 동일한 이름의 멤버가 존재할 경우 우선 사용된다.
3)     사용자 정의 클래스는 Object를 상속하고 Object의 prototype 멤버를 사용할 수 있다. 9번 라인에서 Test클래스에 a 멤버가 없음에도 Object.prototype.a 값이 출력됨을 확인할 수 있다.
4)     사용자 정의 클래스가 상속한 Object의 prototype멤버는 Object의 prototype멤버과 다른 메모리 공간을 갖는다. 
        10번 라인에서 Test.prototype.a 멤버 값을 “b”로 변경한 후 Object.a와 Test.a를 각각 출력해 보면 다른 값을 출력하는 것을 볼 수 있다. 11,12번 라인 참조.
5)    클래스가 new에 의해 객체가 될 때 Object 클래스의 prototype 멤버를 다시 상속받는다. ? 
       객체 멤버와 클래스 멤버는 다른 메모리 공간을 갖는다. 13번 라인의 new Test()에 의해 test 객체는 Object의 prototype 멤버를 객체멤버로 상속받게 되지만 Test클래스의 멤버인 a와는 다른 값을 갖게 된다. 
       14, 15번 라인에서 보여주는 것 처럼 test.a는 Object.prototype.a 값인 “old”를 출력하지만 Test.a는 “b”를 출력하는 것을 볼 수 있다.

 

 

 

 

prototypechain.gif

 



그림 1 prototype chain diagram

 

 


정보 은닉

자바스크립트에서도 클래스의 멤버를 숨기거나(private) 공개(public)할 수 있다. 클래스 멤버를 공개하고자 하는 경우 this 키워드를 사용해 변수나 함수를 정의하면 되고, 숨기고자 할 경우 this 키워드를 사용하지 않으면 된다. 위의 코드에서 “var name = “홍길동”;” 의 문장에 의해 name 변수는 hello 클래스의 private 멤버변수가 되었다. “this.nick = “길동이”;”의 경우 this 키워드에 의해 nick은 public 멤버변수가 되어 hello 클래스를 인스턴스화 한 후 alert(obj.nick); 문장을 사용하여 nick 멤버변수에 정상적으로 접근할 수 있다. 따라서 정상적인 nick의 값이 “길동이”가 출력되게 된다. 하지만 name의 경우 private 멤버변수이므로 alert(obj.name); 문장을 사용할 경우 “홍길동”이 출력되는 것이 아니라 “undefined” 메시지가 출력된다.
메서드의 경우 일반적인 방식대로 function getNick(){…} 문장을 사용할 경우 private 멤버메서드가 되어 외부에서 호출할 수 없고 this.getName = function(){..} 문장을 사용하여 public 멤버메서드를 만들 수 있다.
*Privileaged Member : this 키워드를 사용하여 공개하는 멤버를 Privileaged Member라고 부른다.

 

 

 

 

 

 

 

·미리보기 | 소스복사·
  1. function hello()   
  2. {   
  3.   var name = "홍길동";   
  4.   this.nick = "길동이";   
  5.   
  6.   this.getName = function()   
  7.   {   
  8.     return name;   
  9.   }   
  10.   
  11.   this.setName = function(newName)   
  12.   {   
  13.     name = newName;   
  14.   }   
  15.   
  16.   function getNick()   
  17.   {   
  18.     return this.nick;   
  19.   }   
  20. }   
  21.   
  22. var obj = new hello();   
  23.   
  24. alert(obj.name);        // "undefined" 출력   
  25. alert(obj.getNick());   // "undefined" 출력   
  26. alert(obj.nick);        // "길동이" 출력   
  27. alert(obj.getName());   // "홍길동" 출력  

 

 

 

 

표 4 정보 은닉

 

 

 


JavaScript의 클래스 상속

클래스의 상속은 클래스의 prototype 프로퍼티를 사용한다. 
아래 코드에서 7번 라인은 Child 클래스가 Parent 클래스를 상속하여 Parent의 멤버를 사용할 수 있게 된다는 것을 나타낸다. 
따라서 Child 클래스는 parent 멤버가 없지만 alert(c.parent); 문장을 사용해도 정상적으로 “parent”가 출력되는 것이다.

 

 

 

 

·미리보기 | 소스복사·
  1. 1.   function Parent(arg1) {   
  2. 2.       this.parent = arg1;   
  3. 3.   }   
  4.   
  5. 4.   function Child() {   
  6. 5.       this.child = 'child';   
  7. 6.   }   
  8.   
  9. 7.   Child.prototype = new Parent('parent'); // Child 클래스는Parent 클래스를상속한다.   
  10.   
  11. 8.   var c = new Child();   
  12.   
  13. 9.   alert(c.parent);                // 'parent'   
  14. 10.  alert(c.child);                 // 'child'  

 

표 5 클래스 상속