Javascript prototype 기초

 보통 javascript를 처음 접하게 되는 것은 웹을 공부할 때가 대부분일 것이다.
언어를 배울 때, javascript는 진입 장벽이 낮다고 평가된다. 즉 쉽게 배울 수 있는 언어라는 의미이다.

나 또한 쉽다고 생각을 했었다. 그러나!
prototype이라는 단어를 듣고 그게 뭐지? 라는 생각을 했다.

간단하게 얘기를 하자면 JAVA나 C++ 같은 언어에서는 클래스라는 것이 존재하지만 javascript에는 클래스가 없고, 또한 동적으로 계속 변하는 클래스는 아니면서 클래스의 역할을 하는 녀석이 존재한다.

예제를 한번 보자.
1
2
3
4
5
function Person() { // 클래스의 역할을 한다.
}

var newPerson = new Person();
console.log(newPerson);

function이 클래스의 역할을 하고 또 setter, getter가 따로 없다.





newPerson 객체를 생성하고 log를 찍었을 때의 모습이다.
__proto__라는 녀석이 보일 것이다. 이 속성이 newPerson을 만들기 위해 사용된 객체원형에 대한 숨겨진 연결이다.

 "newPerson 객체의 프로토타입은 어떤 객체이다"라는 것을 알려준다.











이 어떤 객체는 constructor 속성과 __proto__ 속성을 가지고 있는데,
constructor( 생성자)는 function Person() 이라는 의미이다.

new Operator를 통해 만들어진 newPerson객체는 function Person()을 자신의 프로토 타입으로 사용하여 만들어졌다. 즉, "function Person()가 prototype 객체"라고 할 수 있다.




 위 그림을 보면 결국 마지막으로 도달하는 곳은 Object prototype임을 알 수 있다.
결국 객체의 확장은 객체가 소유한 Object prototype을 통해서 이루어 진다.

다음 예제는 prototype의 이해를 돕기 위한 예제이다.

1
2
3
4
5
6
7
8
9
function Person(gender) { // 클래스의 역할을 한다.
  this.gender = gender;   // setter, getter가 따로 없음.
  console.log ('Person instantiated');
};

var newPerson = new Person("female");
console.log(newPerson.gender);

console.log(newPerson.prototype.gender);

 line 7에서는 female 이 출력되고, line 9에서는 syntax error가 발생한다.
error가 발생하는 이유는 newPerson은 함수객체가 아니기 때문이다.
newPerson은 prototype 속성을 갖고 있지 않다.
error가 발생하지 않도록 하기 위해서는 Person.prototype.gender를 출력해야 한다.


"Prototype 속성은 함수 객체만이 갖는 속성"



더 자세한 예제를 보자.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var Person = function () {
  this.gender = function () {
      console.log("my property is this.gender");
  }
}
var p = new Person();
console.log(Person.prototype.gender);
console.log(Person.gender);
console.log(p.gender);

var Person2 = function () {

};
Person2.gender = function () {
  console.log("testing;");
}
Person2.prototype.gender = function () {
  console.log("my property is prototype.gender");
}
var p2 = new Person2();
console.log(Person2.prototype.gender);
console.log(Person2.gender);
console.log(p2.gender);

line 7에서는 prototype 객체를 따로 선언하지 않았기 때문에 "undefined" 출력.

line 8과 22를 비교해보자, 함수 객체는 prototype 객체를 참조한다 또 이 prototype 객체는 결국 prototype Object 를 참조하기 때문에 line 8에서는 prototype Object의 __proto__인 "undefined"를 출력한 것이다.
반면 line 22에서는 함수 객체의 메소드를 정의하고 출력을 하기 때문에 Person2 함수 객체의 속성이 추가된 것이다. 따라서 메소드를 출력할 수 있다.

line 9에서 p는 Person을 프로토타입으로 사용하기 위해서 Person의 프로토타입 객체를 사용할 것이다. 그래서 Person 함수 객체가 생성될 당시 정보를 프로토타입 객체가 알기 때문에 function이 출력 되는 것을 확인 할 수 있다.

 gender라는 메소드를 하위객체에서 찾지 못하면 계속해서 상위객체로 메소드를 탐색한다. 최상위 객체에 도달할 때까지 메소드를 찾지 못하면 "undefined"를 출력하게 된다.
만약 함수 객체 안에 정의된 메소드가 존재한다면 상속으로써의 역할을 하게 된다.



이 블로그의 인기 게시물

웹툰 무료로 볼 수 있는 사이트

BackJoon 1011, Fly me to the alpha centauri, 규칙 찾기 문제

BaekJoon 6591, 이항 쇼다운 조합문제