본문 바로가기
  • think normal
새로워지기/서른의 생활코딩

규이 님이 스프링 노트 < 객체지향 2 >

by 청춘만화 2011. 4. 10.
자바스크립트 관련 이론을 설명해주는 곳은 정말 셀 수 없이 많다.
따라서 어설프게 잘못된 개념을 스스로 작성해서 적는 것 보다는
나보다 더 친절하게 설명해 주시는 분들의 
블로거나 페이지를 소개시켜주는 편이 좋을 것 같다. 

다시말해 자료의 재활용과 기존 블로그들의 재 활성화를 위함이다.


직접적으로 알지는 못하지만 이렇게 인연이 닿아
이런 고수님들을 소개해드릴 수 있게 되어
개인적으로도 영광이다.
작성하신 분들도 앞으로도 이런 영광스러움의 마음이 늘 함께하시길 바란다. 

아, 
삭제를 원하시면 댓글로 말씀하시면 바로 지우겠습니다.
다른 의도는 없었습니다.
미리 양해 말씀 남깁니다.
 

두번째 출처는 
규이 님이 스프링 노트이다.
http://godpage.springnote.com/pages/4223711
이곳에는 자바스크립트는 물론 다양한 프로그렘에 대한 정보도 얻을 수 있다. 




객체

자바스크립트의 모든것은 객체다

-> 객체는 프로퍼티들을 모은것으로 해쉬(hash)자료구조와 거의 같다.

객체생성

대부분의 객체지향언어의 객체생성법

클래스 존재 -> 객체생성 | 클래스에서 상속

자바스크립트의 객체생성법 (프로토타입 상속)

객체 ->  새로운 객체 생성 | 다른객체에서 상속

constructor프로퍼티 : 모든 객체에 들어있으며 객체를 생성한 함수를 가리킨다.

-> 객체를 복사할때 사용

슈퍼클래스와 서브클래스

 Object는 모든 클래스의 슈퍼클래스
즉 위의 Rectangle객체는 Rectangle.prototype 과 Object.prototype의 프로퍼티들을 상속받는다.
Rectangle의 프로퍼티를 찾을경우
1.객체자체의 프로퍼티 검사 (없으면 다음으로 이동)
2.Rectangle.property의 프로퍼티 검사(없으면 다음으로 이동)
3.Object.property의 프로퍼티 검사(다음 없음)

Object의 프로퍼티
constructor - 객체의 생성자인 자바스크립트 함수를 참조

 

 apply() 와 call()메서드

모든 함수에 대하여 call()과 apply()메서드가 정의되어 있음.

this의 의미 변경

 download.png

 

 

public(prototype), privileged(클로저)메서드

public - 공용 메서드

privileged 메서드 : 코드가 처음 컴파일할때 객체에 추가되지 않고 실행중에 추가되므로 동적으로 생성됨. 

 

예제들
  1. /**
     * @author gyus
     */
  2. //객체생성1 - 그냥 생성하기
    var obj = new Object();
  3. obj.val = 5;
    obj.click = function(){
     alert("obj click ok");
    }
  4. //객체생성2 - JSON으로 {키:값} 방식으로 생성
    var obj2 = {
     val : 5,
     click : function(){
      alert("obj2 click ok");
     }
    }
  5. //obj.click();
    //obj2.click();

  6. //클래스 역활을 하는 함수 선언
    function Movie(title){
     this.title = title;
    }

  7. //함수로부터 객체생성 and constructor property
    var movie1 = new Movie("G.I.Joe");
  8. //alert("movie's Title : " + movie1.title);
  9. //alert(movie1.constructor);
    //alert(movie1.constructor == Movie);
  10. //생성자함수도 함수니깐 그냥 실행하면 어떻게 되나? this가 가리키는것은?
  11. Movie('The Lord of the ring');
  12. //-> 전역범위의 this가 되므로 window의 프로퍼티가 됨.
    //alert(window.title);
  13. //Construnctor 2번째
    function Supplies(){} //물품 생성자 함수
  14. var pencil = new Supplies(); //연필객체 생성
    //constructor 생성자 함수로 지우개 생성
    var eraser = new pencil.constructor(); // == Supplies() 새로운 객체를 쉽게/효과적으로 복제가능하다!
  15. //alert("Constructor check : " + pencil.constructor == eraser.constructor);

  16. /*** public(prototype), private(내부함수), privileged(클로저)메서드 ***/
  17. //prototype 프로퍼티를 통해 메서드를 추가
    function User(name, age){
     this.name = name;
     this.age = age;
    }
  18. User.prototype.getName = function(){
     return this.name;
    }
  19. User.prototype.getAge = function(){
     return this.age;
    }
  20. var user = new User("승규", "28");
  21. //확인해보기~
    //alert("name : " + user.getName() + "  |  age : " + user.getAge() );
  22. //privileged 메서드 : 코드가 처음 컴파일할때 객체에 추가되지 않고 실행중에 추가되므로 동적으로 생성됨.
    //prototype메서드를 만드는 방식보다는 비효율적이지만 더 유연하다! -> 많이 쓸수 있다.
    function User2(name, age){
     
     //유저의 태어난년도 계산하기
     var year = (new Date()).getFullYear() - age;
     //year 변수에 접근 가능 & 외부에서도 사용가능한 privileged 메서드를 만든다.
     this.getYearBorn = function(){
      return year;
     }
    }
  23. var user2 = new User2("박씨","28");
    //alert(user2.getYearBorn());
  24. //객체의 private 프로퍼티인 year에는 접근 불가
    //alert(user2.year);

  25. /**
     * 변수를 private로 지정하기
     */
  26. function Rectangle(w,h){
     //이 생성자는 초기화시킬 객체의 width와 height 프로퍼티를 저장하지 않는다.
     //대신에 객체의 접근 메서드를 정의한다.
     //이 메서드들은 클로저이며, width와 height는 유효범위(함수) 체인 안에 있다.
     this.getWidth = function(){return w;}
     this.getHeight = function(){return h;}
    }
  27. //메서드 추가
    Rectangle.prototype.area = function(){
     return this.getWidth() * this.getHeight();
    }
  28. var r1 = new Rectangle(10,5);
  29. //alert("width : " + r1.w);  //undifined
    //alert("height : " + r1.h); //undifined
  30. //alert("width : " + r1.getWidth());
    //alert("height : " + r1.getHeight());
    //alert("area : " + r1.area());
  31. //toString 메서드 만들기
    Rectangle.prototype.toString = function(){
     return "[Width : "+this.getWidth()+" ]\n"
       +"[Height : "+this.getHeight()+" ]\n"
       +"[Area : "+this.area()+" ]";
    }
  32. //alert(r1.toString());
  33. //슈퍼클래스와 서브클래스 (prototype상속)
  34. /**
     * Object의 메서드
     *
     * hasOwnProperty() - 지정된 프로퍼티가 있는지 검사
     * isPropertyOf() - 이 객체가 지정된 객체의 프로토타입 객체인지 검사
     * propertyIsEnumerable() - 지정된 프로퍼티가 존재하는지, for/in루프가 가능한지 검사
     * toLocaleString() - 객체의 지역화된 문자열 표현리턴 보통 toString()을 호출하나 overiding가능
     * toString() - 객체의 문자열 표현을 리턴
     * valueOf() - 객체와 관련된 기본값이 존재한다면 이를 리턴
     */

  35. //call & apply this의 의미 변경하기
    function plus(x, y){
     alert(x + " + " + y + " = " + (x + y));
    }
  36. function minus(x, y){
     alert(x + " - " + y + " = " + (x - y));
    }
  37. function multi(x,y){
     alert(x + " x " + y + " = " + (x * y));
    }
    function arithmatic(x, y, operator){
     if(operator == "plus")
      plus.call(this, x, y);
     else if(operator == "minus")
      minus.apply(this,[x,y]);
     else if(operator == "multi")
      multi.call(this, x, y);
     
    }
  38. new arithmatic(1,2,'plus');
    new arithmatic(1,2,'minus');
    new arithmatic(3,5,'multi');

  39.  //Rectangle 클래스를 상속받는 클래스를 만들어보자
     //위치에 대한 정보를 가지고 있는 사각형 클래스
     function PositionedRectangle(x,y,w,h){
      //새로운 객체의 슈퍼클래스 생성자를 호출
     //초기화될 객체의 메서드로 생성자를 호출할 수 있게 call()메서드를 사용.
     //생성자 체이닝(chaining) 기법이라고 부름
     Rectangle.call(this,w,h);
     this.x = x;
     this.y = y;
     }
     
    //new PositionRectanlge()을 사용하면 슈퍼클래스가 Object가 되므로 슈퍼클래스를 Rectangle로 지정해준다.
    PositionedRectangle.prototype = new Rectangle();
  40. //필요없는 프로퍼티를 삭제한다.
    delete PositionedRectangle.prototype.width;
    delete PositionedRectangle.prototype.height;
  41. //프로토타입 객체가 Rectangle()을 사용하여 만들어졌기에
    //constructor프로퍼티는 Rectangle()생성자를 참조한다.
    //그렇지만 생성자가 PositionedRectangle()이 되기를 원하므로
    //constructor의 프로퍼티를 다시 참조한다.
    PositionedRectangle.prototype.constructor = PositionedRectangle;
    //원하는 객체가 생성되었다.
  42. //여기에 메서드 추가 가능
    PositionedRectangle.prototype.contains = function(x,y){
     return(x > this.x && x< this.x + this.width && y> this.y && y < this.y + this.height);
    }
  43. //결론 : 서브클래스 만드는건 생각보다 까다롭다.
    //만드는 절차
    //1. 서브클래스의 생성자에서 슈퍼클래스의 생성자호출
    //2. 프로토타입객체를 명시적으로 슈퍼클래스의 인스턴스로 만들기
    //3. 그후 프로토타입 객체의 constuctor프로퍼티를 명시적으로 설정해주기
    //4. 슈퍼클래스의 생성자에서 만든 프로퍼티가 필요없는 경우 삭제
  44. var r2 = new PositionedRectangle(2,2,2,2);
    //alert(r2.contains(3,3));
    //alert(r2.area());
  45. //alert(r2.x + " | " + r2.y + " | " + r2.width + " | " + r2.height);
  46. //alert(r2 instanceof PositionedRectangle && r2 instanceof Rectangle && r2 instanceof Object);
  47. //오버라이딩을 하지 않았으므로 Rectangle의 메서드가 호출됨
    //alert(r2.toString());
  48. //생성자 체이닝
    PRectangle.prototype.superclass = Rectangle;
    function PRectangle(x,y,w,h){
     //상위클래스의 생성자 함수
     this.superclass(w,h);
     this.x = x;
     this.y = y;
    }

  49. //오버라이드 toString()
    PRectangle.prototype.toString = function(){
     return "(" + this.x + "," + this.y + ")" + this.superclass.prototype.toString.apply(this) //PositionedRectangle의 필드를 상위클래스에 체이닝
    }

댓글