prototype
이란 무엇이고 어떻게 써야 할건가 ?

var man = function(name){   

     this.name = name;   

}   

  

var niceguy = new man('멋진인생');   

  

alert(niceguy.name);  


생성자 함수를 사용하여 객체를 하나 생성했습니다. 객체의 프로퍼티에 접근하기 위해선 상기 소스 처럼 사용해도 되나.. 우리는 인스턴스 메소드를 사용해서name 을 가져오는 getName 메소드를 만들어 보도록 할겁니다


var man = function(name){   

     this.name = name;   

     this.getName = function(){   

        alert(this.name);   

     }   

}   

  

var niceguy = new man('멋진인생');     

niceguy.getName();   

  

var panda     = new man('쿵후팬더');     

panda.getName();   


그러나 객체 마다 name 프로퍼티와 getName  메소드가 포함되어 있습니다..
name 프로퍼티는 각 객체 마다 값이 틀리지만 getName  메소드는 동일한 메소드이기 때문에
객체마다 메소드가 존재해서 부피를 키우는 꼴이 되는거죠.. 그럼 다른 방법은 없을까요


var man = function(name){   

     this.name = name;   

}   

  

var getName = function(){   

      alert(this.name);   

}     

  

var niceguy = new man('멋진인생');     

getName.call(niceguy);   

  

var panda     = new man('쿵후팬더');     

getName.call(panda)


근데 사실 이렇게 함수로 빼서 call, apply 등으로 사용하게 되면, 일단 하나의 함수로 다같이 사용하는건 맞습니다.
근데 이렇게 되었을시 일단 지저분하고, 메소드가 계속 추가 되었을시 관리는 누가 하나요???(전 못합니다-_-;;;)
사실 모듈화된javascript 를 잘 만들려면 객체형식으로 분리해서 관리 하여야 합니다.. 이제 최종적으로 수정해 볼까요


var man = function(name){   

     this.name = name;   

}   

  

man.prototype.getName = function(){   

    alert(this.name);   

}   

  

var niceguy = new man('멋진인생');     

niceguy.getName();   

  

var panda     = new man('쿵후팬더');     

panda.getName();


function 함수엔 Prototype 객체를 가르키는 prototype 이란 프로퍼티가 하나 존재합니다.
Prototype 객체에 공유되어 있는 프로퍼티와 메소드가 객체 생성시 해당 생성자 function 으로 생성한
모든 인스턴스에서 공유됩니다...

모든 function 에는 Prototype 객체를 가르키는 prototype 이라는 프로퍼티가 있다고 했습니다.
prototype 에는 사실 딱 하나의 프로퍼티가 존재 합니다. 그 이름하여 constructor 입니다



var man = function(name){   

    this.name = name;   

    this.getName = function(){   

        alert(this.name);   

    }   

}   

  

alert(a.prototype.constructor);  


해당prototypeconstructorprototype을 가지고 있는 function을 가르킵니다.
어떻게 prototype 에서 각 객체의 인스턴스로 프로퍼티들을 공유 할까요
그건 상속과도 비슷한 개념입니다


var man = function(name){   

    this.name = name;   

}   

  

man.prototype.getName = function(){   

        alert(this.name);                      

}   

  

  

var niceguy = new man("멋진인생");   

niceguy.getName();  


man 생성자 함수를 통하여 객체를 생성했습니다.
niceguy
인스턴스에는 분명 getName이 존재 하지 않으나 getName은 정상적으로 작동하게 되죠.
최초 호출시 man 자체에서 getName을 찾아 봅니다. 당연히 없겠죠..
그럼 man.prototype 에서 getName 을 찾아 봅니다. 물론 있습니다.. 그럼 반환하겠죠
....
만약 man.prototype 에서 조차도 없다. 그럴땐 더 상위로 가봅니다
..
Object.prototype 에서 찾아 보는겁니다
이마저 없을땐 오류가 발생하는거죠

두번째 코드에서 내용이 틀렸습니다.
man.prototype.getName 을 참고하는게 아니라 man.__proto__.getName을 참고합니다.

niceguy를 생성한후
man.prototype = {}; 로 man.prototype.getName을 삭제해줘도 niceguy.getName()은 여전히 호출되는것을 확인하실수 있습니다


 




관련 소스를 하나 볼까요

var man = function(name){   

    this.name = name;   

    this.getName = function(){   

        alert('man:' + this.getName);   

    }   

}   

  

man.prototype.getName = function(){   

        alert('man.prototype:'+this.name);                     

}   

  

  

Object.prototype.getName = function(){   

        alert('Object.prototype:'+this.name);                      

}                  

  

var niceguy = new man("멋진인생");   

niceguy.getName();  


man getName 을 가져오는군요....
이렇듯prototype 베이스 상속이란건 실제로 값을 가져다가 복사하는게 아닌
상위로 찾아가면서 값을 구하는 거예요..
그럼prototype 에서의 읽기는 그렇다 치고 쓰기는 어떨까요


1.     var man = function(name){   

2.         this.name = name;   

3.     }   

4.       

5.     man.prototype.age = '13'  

6.       

7.     var niceguy = new man('멋진인생');   

8.       

9.     alert(niceguy.age) // 13 반환
 
  

10.   alert(niceguy.hasOwnProperty("age")); // false 반환
 
  

11.   niceguy.age = '14';
   

12.   alert(niceguy.age)   // 14 반환
        
  

13.   alert(niceguy.hasOwnProperty("age")); // true 반환


age 프로퍼티를 하나 추가하려 합니다..
보통 man 자체에 넣겠지만 prototype 에 넣어 보도록 하죠...
그럼 최초에 niceguy.age 호출시 man 에 있는지 확인 합니다.. 물론 없습니다.
그럼 man.prototype 에서 찾아 봅니다.. 자 있습니다.. 13을 반환 합니다.

niceguy.hasOwnProperty
를 호출 합니다.
hasOwnProperty
메소드는 해당 객체 자체에 있는 프로퍼티 일 경우는 true ,
prototype
등으로 상속 받은 경우는 false 를 반환 합니다..
당연히 man.prototype 에서 가져온age 이기 떄문에 false 를 반환 합니다.

그 뒤에 niceguy.age 의 값을 변경해 봅니다..
이때 주의하셔야 할것이 man.prototype age 의 값을 변경하지 않는다는 겁니다..
man
자체에 age 란 변수를 만들고 그뒤에14 값을 넣습니다..
이제 niceguy.hasOwnProperty 를 호출하면 true 를 반환 하는것을 알수 있습니다..

prototype을 사용하실때 주의 하셔야 할점도 있습니다.
prototype.js
를 보신분들은 알고 계시겠지만 내장 타입도 확장을 함으로써 편하게 사용하실 수 있게 만들어 놨습니다


Array.prototype.clear = function(){   

        this.length = 0;   

}   

  

var arr = [1, 2, 3];   

  

alert(arr); //[1, 2, 3]   

  

arr.clear()   

  

alert(arr); // []


상기 소스 처럼 내장 타입도 확장할수 있지만 Object.prototype 만은 테스트 용도가 아닌경우 확장 하길 권하지 않습니다...
왜 그런지는 충분히 아실거라 생각합니다......
사실prototype 은 저정도 이외에도 내부적으론 좀더 복잡하게 돌아가는거 같습니다만



+ Recent posts