본문 바로가기

Front-End/

Prototype, Object 이해하기

Prototype이란 무엇인가?

  • Java에서와 다르게 Javascript는 프로토타입 기반의 언어라고 한다. 항상 귀동냥으로 자바는 객체지향 언어이고 이는 자바스크립트에서 지원이 되지 않는다고만 알고 있었다. ( ECMA2016에서 class 키워드가 등장하긴 했지만... )

  • 공부를 하다보니 Object가 무엇인지도 제대로 안 되어 있음

Object란 무엇인가?

  • Object란 객체이다. 객체란 Java에서 배웠던 것 처럼 데이터(주체)와 행동(데어터에 관련된 동작)을 정의하고 있는 것이다. 자바스크립트는 객체 그 자체라고 하는데, 이것이 어떠한 의미인지는 아직 와닿지는 않는다. 

  • 위에서 정의한 것처럼 흔히 데이터는 프로퍼티라 칭하고, 행동은 메소드라 칭한다.

Property

프로퍼티는 객체의 속성을 나타내는 접근 가능한 이름과 활용 가능한 값을 가진 것이다. 

var person = {};  // Person 객체 생성
person.age = 28; // . 연산자를 이용하여 프로퍼티 생성
var age2 = person.age+1;
console.log(Person.age);

여기서 Java와의 차이때문에 궁금한 점이 생긴다.
  • age라는 프로퍼티가 없었는데, 할당이 되네? 생성할 때 값을 할당하지 않으면 어떻게 될까?

person.name;

과 같이 실행을 하면 syntax error가 난다. 그 이유는 프로퍼티를 추가하면서 값을 안쓰는 경우를 허락하지 않기 때문이다. 

Method

메소드는 객체가 가지고 있는 동작이다. 

var foo={};
foo.a=1;
foo.b=2;
foo.sum=function(){console.log(foo.a+foo.b)};;
foo.sum();

자바스크립트 Object의 구성
  1. Built-in Object ( 자바스크립트 내장 객체 )
    • Object,String,Number,Boolean,Array 등과 같은 객체를 말한다. 자바스크립트 엔진이 구동될 때 부터 사용이 가능하다.
  2. Native Object ( 브라우저 내장 객체 )
    • Native Object 또한 자바스크립트 엔진이 구동될 때부터 사용이 가능하다. DOM(문서객체모델)과 같은 것인데, 자바스크립트 엔진을 구동하는 녀석들이 빌드하는 객체이다. 
    • 브라우저가 만들어주는 객체이다.
  3. Host Object ( 사용자 정의 객체 )
    • 우리가 정의한 객체이다. Built-in, Native Object가 구성된 이후에 구동된다.

자바스크립트 객체는 어떻게 생성하냐?
  1. constructor 이용

var person = new Object();
person.name = 'Boris';
person.age = 28;
  1.  JSON 이용

var person = {
    name : 'Boris'
    age : 28;
}

Object 객체
자바스크립트에서 정의한 객체는 모두 Object 객체에서 파생되어 나왔다.
var foo = { name : 'foo' }
console.log(foo);



Object의 구성을 살펴보면, constructor, _proto_와 같은 것이 보인다. 이것이 처음에 공부하려 했던 prototype과 관련된 내용같다.

Object의 배열 상속
밑의 예제를 살펴보면 객체는 결국 property 배열의 집합체이며 chain 연결 구조로 되어 있다. ( 왜 이렇게 되어 있는지 좀더 자세한 내용은 추후에 더 조사를 해봐야겠다. )
var foo = {name : 'foo' }
console.log(foo['name']);
Object를 이해를 해야 this, prototype, execution context와 같은 것을 이해하기 쉽다고 한다. ( execution context와 this는 따로 올리도록 하겠습니다. )

다시 Prototype 시작

Prototype 사용 예제
function Person() {
    this.eyes = 2;
    this.nose = 1;
}

var kim = new Person();
var park = new Person();

console.log(kim.eyes); // => 2
console.log(kim.nose); // => 1


console.log(park.eyes); // => 2
console.log(park.nose); // => 1

이 부분이 내가 알던 클래스 개념과 같다. 클래스를 정의하고 각자 메모리를 할당하여 사용하는 것이다. 

그런데 이렇게 관리를 하면 안되는 경우가 있어서 프로토타입을 사용한다고 한다. 도대체 왜?

function Person() { }

Person.prototype.eyes = 2;
Person.prototype.nose = 1; 

var kim = new Person();
var park = new Person();

...

다음과 같이 선언하면 eyes,nose는 kim과 park에 각각 할당되는 것이 아니다. 즉, 메모리에는 eyes,nose 각각 1개씩만 적재되는 것이다.

Prototype이 왜 쓰이는가?

 메모리를 적게 할당한다는 건 알겠는데 도대체 왜 쓰는건지는 아직 이해가 안된다.  이를 이해하기 위해서는 Prototype Object, Prototype Link라는 것을 이해해야 한다.

Prototype Object 
모든 객체(Object)의 조상은 함수(Function)이다.

function Person () {} // 함수
var personObj = new Person(); // 함수로 객체를 생성

var obj = { };    // var obj = new Object(); 와 같은 의미

obj를 출력해보면 function obj() { [native code] }가 나온다. 이 뜻은 결국 모두 함수로 정의되어 있다는 것이다. 

그렇다면 이 내용이 Prototype Object와 무슨 관련이 있는가? 

new Person()을 할 때 위에서 본 것 처럼 함수만 정의되는 것이 아니라 이 때 Prototype Object도 생성된다!


생성된 함수는 prototype 이라는 property를 통해 prototype object에 접근할 수 있다.
오른쪽 박스가 Prototype Object가 생성된 것인데, constructor와 _proto_변수가 있다.


지금까지 살펴본 부분을 다시 정리해보면 다음과 같다.
  • 함수가 정의될 때 이루어지는 일들 ( function Person() { ... } )
  • Prototype Object에 대하여

Prototype Link

밑의 그림은 Person을 할당한 kim과 kim.eys를 출력한 화면이다. 
하지만, kim에는 eyes라는 property가 없는데 어떻게 이게 가능할까?


위에서본 function Person()이 가지고 있는 prototype과 달리,
모든 객체는 _proto_ 속성을 가지고 있다.

이 _proto_ 속성 덕분에 eyes를 찾을 수 있는 것이다. 그렇다면, 어떻게 찾아지는지 살펴보자.




  1. kim._proto_ 는 function Person()이 생성될 때 만들어진 Person Prototype Object를 가리키고 있다.
  2. Person Prototype Object에서 eyes를 찾을 수 있다.
  3. (만약 eyes가 없었다면) Person Prototype Object의 _proto_를 따라간다. 이는 상위 prototype object를 바라본다. ( 부모 자식 관계를 어떻게 맺는지는 다음 포스팅에서 )
    이렇게 연결되어 있는 것을 Prototype Chain이라 부른다.
  4. 최상위인 Object Prototype Object까지 찾아보고 없다면 undefined를 반환해준다.

마무리

Prototype과 Object에 대해 알아보았지만, Prototype의 진정한 가치를 아직 이해는 못하겠다. 자바스크립트 코딩을 해보면서 알게 되길 바란다.


'Front-End > ' 카테고리의 다른 글

Functions  (0) 2018.04.12
Web Worker(웹 워커) - 멀티 스레드 쓰고 싶어!  (0) 2018.02.21
Closure  (0) 2017.06.20
Shadow DOM  (0) 2017.04.28
문서 스크립팅  (0) 2017.04.27