자바스크립트.js #3 참조(객체) 타입

김창회·2020년 12월 29일
3

자바스크립트.js

목록 보기
3/8
post-thumbnail

💻자바스크립트.js 시리즈는 자바스크립트에 대해 심플하게 훑어봅니다📖


데이터 타입

자바스크립트의 값들은 크게 기본 타입과 참조 타입으로 나뉩니다.

이전 게시글에선 기본 타입에 대해 살펴봤고,
이번에는 참조(객체) 타입에 대해 살펴보도록 하겠습니다.

객체

참조 타입에 알아보기 전에 모든 값의 어머니 격인 객체에 대해 먼저 알아보겠습니다.
왜 어머니일까요? 자바스크립트에서 기본 타입을 제외한 모든 값은 객체이기 때문입니다.
배열, 함수, 정규표현식 등 결국 자바스크립트의 객체 안에 존재합니다.
참조 타입 역시 곧 객체이며 참조 타입의 근원에는 객체가 있다고 볼 수 있겠습니다.

객체 생성

객체는 '이름(key) : 값(value)' 형태의 프로퍼티들을 저장하는 컨테이너입니다.

객체를 생성하는 방법은 크게 세 가지가 있습니다.

  • Object() 객체 생성자 함수
  • 객체 리터럴
  • 생성자 함수

Object() 객체 생성자 함수

Object() 객체 생성자 함수는 내장되어 있는 함수입니다.
예제 코드를 보며 어떻게 생성하는지 살펴보겠습니다.

EX

const obj = new Object();

obj.name = "chkim132";
obj.title = "자바스크립트.js";

console.log(typeof obj); // object
console.log(obj); // { name : "chkim132", title : "자바스크립트.js" }

객체 리터럴

우선, 리터럴이란 고정된 값이라는 의미로
데이터 그 자체를 뜻하며, 변수에 넣는 변하지 않는 데이터입니다.
쉽게 표기법이라고 생각하면 쉬울 거 같습니다.

객체 리터럴은 중괄호 {}를 이용해 생성할 수 있습니다.
프로퍼티(속성)값으로는 어떤 표현식도 올 수 있고, 함수일 경우엔 메서드라고 칭합니다.

똑같은 obj 변수를 객체 리터럴로 생성한 예제입니다.

EX

const obj = { name : "chkim132", title : "자바스크립트.js" };

console.log(typeof obj); // object
console.log(obj); // { name : "chkim132", title : "자바스크립트.js" }

생성자 함수

자바스크립트에서는 함수를 통해서도 객체를 생성할 수 있습니다.
앞서 객체 생성자 함수에서 사용했던 new라는 연산자를 응용하면 됩니다.

function Person(name, title) {
  this.name = name;
  this.title = title;
}

const me = new Person("chkim132", "자바스크립트.js")
console.log(me); // { name : "chkim132", title : "자바스크립트.js" }

생성자 함수(여기선 Person)의 경우 구분하기 위해 첫 문자를 대문자로 쓰기를 권고하고 있다.

객체 프로퍼티 접근/생성 및 갱신/삭제

객체는 새로운 값을 가진 프로퍼티를 생성하고, 그 프로퍼티에 접근해 값을 읽거나 원하는 값으로 갱신할 수 있습니다.

객체 프로퍼티 접근

접근하기 위해선 두 가지 방법을 사용합니다.

  • 대괄호 표기법 ex) obj['value']
  • 마침표 표기법 ex) obj.value

EX

const obj = { value : "Hello"};

console.log(obj['value']);  // Hello
console.log(obj.value); // Hello

만일, 프로퍼티 값이 없다면 undefined가 출력됩니다.

console.log(obj.name); // undefined

객체 프로퍼티 생성 및 갱신

갱신하기 위해선 우선 객체의 프로퍼티에 접근해야 합니다.

EX

const obj = { value : "Hello"};

obj['value'] = "Hi"

console.log(obj['value']);  // Hi

만약 프로퍼티가 존재하지 않아도 위와 같은 방법으로 생성할 수 있습니다.

console.log(obj.name); // undefined

obj.name = "chkim132";

console.log(obj.name); // chkim132

객체 프로퍼티 삭제

delete 연산자를 이용하면 객체의 프로퍼티를 삭제할 수 있습니다.
단, 주의할 점은 객체의 프로퍼티만 삭제하지 객체 자체를 삭제하지는 못합니다.

EX

const obj = { name : "chkim132", value : "Hello"};

delete obj.value;

console.log(obj); // { name : "chkim132" }

참조 타입

객체에 대해 알아봤으니 이제 참조 타입에 대해 살펴보겠습니다.
객체를 두고 자바스크립트에서는 참조 타입이라고 부르고 있습니다.

참조란

참조(reference)란 값의 복제가 아닌 실체 값을 빌려와 사용하는 걸 뜻합니다.

EX)

const a = { value: "a"};
const b = a;

b.value = "b";

console.log(b.value); // "b"
console.log(a.value); // "b"

b에 a를 할당한 뒤, b.value = "b"로 값을 변경시켰음에도 a.value 역시 "b"로 변했습니다.

왜 이렇게 됐을까요?

사실 a라는 변수는 객체 자체를 저장한 게 아닌, 생성된 객체를 가리키는 참조값을 저장했기 때문입니다. 즉 변수에 객체를 생성해도 변수엔 실체 자체를 저장하지 않고 참조한 값을 저장하기 때문에 결국 a나 b 모두 같은 객체의 값을 갖고 있게 되는 겁니다. b를 변환하면 실체 자체가 변하게 되고 실체를 참조한 a의 값 역시 변하게 되는 것입니다.

객체 비교

객체를 비교할 때엔 프로퍼티가 아닌 참조값을 비교하게 됩니다.

EX

const obj = { name : "chkim132" };
const obj2 = { name : "chkim132" };

console.log(obj === obj2); // false;

obj와 obj2는 같은 프로퍼티를 갖고 있는데 false를 반환하고 있습니다.
서로 다른 참조값을 갖고 있기 때문입니다.

만약 obj3라는 변수에 obj를 할당하고 비교해보면 어떻게 될까요?

const obj3 = obj;

console.log(obj === obj3); // true

true를 반환합니다.
이런 이유는 앞서 말했듯 똑같은 본체에서 참조하고 있기 때문입니다.

함수 호출 방식의 차이

기본 타입과 참조 타입의 차이는 함수 호출 방식에서도 차이가 있습니다.
기본 타입의 경우는 값에 의한 호출 (Call By Value)이고,
참조 타입의 경우 참조에 의한 호출 (Call By Reference) 방식으로 동작합니다.

함수를 호출해 인자로 값을 넘길 경우
기본 타입의 값은 복사되어 함수 내부로 전달됩니다.
복사된 값이기 때문에 복사된 값을 아무렇게나 바꿔도 실제로 변수의 값이 변경되진 않습니다.

하지만 참조 타입의 경우 참조된 값이 함수 내부에 들어가기 때문에
함수 내부에서 변경된 값이 고스란히 반영됩니다.

EX

const string = "hi?";
const obj = { say : "hi?" };

function printHello(string, obj) {
  string = "Hello!";  
  obj.say = "Hello!";
  
  console.log(string); // Hello!
  console.log(obj.say); // Hello!
};

printHello(string, obj);

console.log(string); // hi?
console.log(obj.say); // Hello!

위의 예제와 같이 문자열을 할당한 string 변수는 변하지 않았지만
참조값인 obj 객체는 값이 변했습니다.

프로토타입

모든 객체는 자신의 부모 역할을 하는 또다른 객체와 연결되어 있습니다.
그러니까 엄마의 엄마, 즉 할머니가 계시는 격입니다.
자바스크립트에선 이 객체를 뭐라고 부르고 있을까요? 바로 프로토타입 객체라고 부릅니다.

자바스크립트는 기본적으로 프로토타입 기반 언어입니다.
우리가 객체를 생성하면 생성된 객체 위로 프로토타입이 생성됩니다.
우리가 toString()이라는 메서드를 객체에서도 사용할 수 있는 비결이 바로 이곳에 있습니다.


위 사진처럼 Object.prototype에 toString()이라는 메서드가 기본 장착 되어 있기 때문입니다.

배열의 경우는 어떨까요?


배열의 경우엔 Array.prototype과 그 위에 Object.prototype 객체를 가집니다.

그런데 여기서 잠깐, 생성시 갖게 된 프로토타입을 바꿀 수는 없을까요?
물론 프로토타입은 동적으로 바꿀 수도 있습니다.
하지만 그건 나중에 자세히 알아보겠습니다😊


마무리

이상으로 객체와 참조 타입에 대해 알아봤습니다.
다음 게시글에선 자바스크립트의 객체 중 하나인 배열을 훑어보는 시간을 갖겠습니다🙂

출처

  • 인사이드자바스크립트
profile
프론트엔드 개발자

1개의 댓글

comment-user-thumbnail
2021년 1월 3일

잘보고갑니다!

답글 달기