인사이드 자바스크립트를 공부하며 정리하는 포스팅입니다.



참조 타입(객체)


자바스크립트에서 기본 타입을 제외한 모든 값은 객체다.

따라서 배열, 함수, 정규표현식 등도 결국 자바스크립트 객체로 표현된다.

자바스크립트에서 객체는 단순 key : value 형태의 프로퍼티들을 저장하는 컨터이너로써, Hash와 유사하다. 
프로퍼티에는 기본 타입, 참조 타입(객체), 함수등 모든 타입을 포함할 수 있다.



1. 객체 프로퍼티 접근


객체 프로퍼티를 읽고, 쓰고, 갱신하기 위해 접근하는 방법은 두 가지가 있습니다.


- 대괄호([]) 표기법

- 마침표(.) 표기법


일반적으로는 C++, Java등의 언어와 유사하게 마침표 표기법을 많이 사용하지만 대괄호 표기법만을 사용해야하는 경우가 있습니다.

1) 프로퍼티 이름이 표현식인 경우 // foo['full-name'] = 'foo song';

2) 프로퍼티 이름이 예약어인 경우 




2. for in 문


for in 문을 사용하면, 객체에 포함된 모든 프로퍼티에 대해 루프를 수행할 수 있습니다.

var objA = {

val : 40

};



var objB = objA;



console.log(objA.val); // 40

console.log(objB.val); // 40



objB.val = 50;



console.log(objA.val); // 50

console.log(objB.val); // 50
for in 문을 수행하면서 변수에 객체의 프로퍼티가 하나씩 String 타입으로 할당됩니다.



3. 객체 프로퍼티 삭제


자바스크립트에서는 객체의 프로퍼티를 delete 연산자를 이용해 즉시 삭제할 수 있습니다.


delete foo.name;


4. 참조 타입의 특성


자바스크립트에서 객체는 참조 타입입니다. 

말그대로 객체의 모든 연산이 실제 값이 아닌 참조값으로 처리되기 때문입니다.

var objA = {

val : 40

};



var objB = objA;



console.log(objA.val); // 40

console.log(objB.val); // 40



objB.val = 50;



console.log(objA.val); // 50

console.log(objB.val); // 50

objB의 프로퍼티를 수정해도 objA의 프로퍼티가 같이 수정됩니다. 따라서 두 객체는 같은 객체를 가리키고 있다는 것을 알 수 있습니다.


var objA = {}; 


위와 같이 객체를 생성되면 objA 자체의 값이 객체인 것이 아니라 생성된 객체를 가리키는 참조값을 저장하고 있는 것입니다.

 

객체비교도 마찬가지 입니다.

var objA = {

val : 40

};



var objB = {

val : 40

};



var objC = objB;



console.log(objA == objB); // false

console.log(objB == objC); // true

변수는 객체의 값이 아닌 객체의 참조값을 가지고 있기 때문에 모든 값이 동일한 objA와 objB는 다른 객체이고, 참조값이 같은 objB와 objC는 같습니다.


* 다음 포스팅에 깊은복사와 객체간 값 비교를 통해 비교하는 함수를 만들어 보도록 하겠습니다. 



4. 참조에 의한 호출 방식 (call by reference)


기본 타입과 참조 타입의 경우는 함수 호출 방식도 다릅니다. 기본 타입의 경우는 call by value/ 참조 타입은 call by reference 입니다.


call by value: 함수를 호출할 때 인자로 복사된 값을 전달한다. 즉, 함수내에서 매개변수의 값을 변경해도 실제 값은 변경되지 않는다.

call by reference: 함수를 호출할 때 인자로 객체의 참조값이 전달된다. 즉, 함수내에서 매개변수의 값을 변경하면 실제 값이 변경된다.


위에서 4. 참조 타입의 특성으로 보면 알 수 있듯이 참조 타입은 값 자체가 아닌 가리키고 있는 참조값입니다. 때문에 함수 내에서 인자로 받은 객체의 프로퍼티를 수정하면 원본 객체의 프로퍼티가 수정됩니다.


c++을 하셨던 분들은 포인터를 생각하시면 이해가 빠를듯 합니다. 변수에 할당된 것은 값이 아니고 주소이고, 그 주소에 있는 값을 변경하는 것이라고 생각하시면 됩니다.



5. 프로토타입


자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있습니다. 마치 객체지향의 상속과 유사하게 부모 객체의 프로퍼티를 자신의 것처럼 사용할 수 있습니다. 자바스크립트에서는 이러한 부모 객체를 프로토타입이라고 부릅니다. 


ECMAScript 명세서에는 자바스크립트의 모든 객체는 자신의 프로토타입을 가르키는 [[Prototype]]이라는 숨겨진 프로퍼티를 가진다고 설명합니다. 이를 크롬 브라우저에서는 _proto_라 되어있습니다.



foo 객체의 프로토타입 객체는 Object.prototype 객체입니다. (객체의 최상위 프로토타입) 따라서 foo 객체는 Object.prototype에 정의된 프로퍼티들을 사용할 수 있습니다.


자바스크립트에서 굉장히 중요한 개념입니다. 이후에 따로 프로토타입, 프로토타입 체이닝, 상속에 관하여 심도있게 포스팅을 작성해볼 예정입니다^^.