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의 구성
- Built-in Object ( 자바스크립트 내장 객체 )
- Object,String,Number,Boolean,Array 등과 같은 객체를 말한다. 자바스크립트 엔진이 구동될 때 부터 사용이 가능하다.
- Native Object ( 브라우저 내장 객체 )
- Native Object 또한 자바스크립트 엔진이 구동될 때부터 사용이 가능하다. DOM(문서객체모델)과 같은 것인데, 자바스크립트 엔진을 구동하는 녀석들이 빌드하는 객체이다.
- 브라우저가 만들어주는 객체이다.
- Host Object ( 사용자 정의 객체 )
- 우리가 정의한 객체이다. Built-in, Native Object가 구성된 이후에 구동된다.
자바스크립트 객체는 어떻게 생성하냐?
- constructor 이용
var person = new Object();
person.name = 'Boris';
person.age = 28;
- 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를 찾을 수 있는 것이다. 그렇다면, 어떻게 찾아지는지 살펴보자.
- kim._proto_ 는 function Person()이 생성될 때 만들어진 Person Prototype Object를 가리키고 있다.
- Person Prototype Object에서 eyes를 찾을 수 있다.
- (만약 eyes가 없었다면) Person Prototype Object의 _proto_를 따라간다. 이는 상위 prototype object를 바라본다. ( 부모 자식 관계를 어떻게 맺는지는 다음 포스팅에서 )
이렇게 연결되어 있는 것을 Prototype Chain이라 부른다. - 최상위인 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 |