Skip to content

Tags

On this page

JavaScript 객체

객체란?

자바스크립트에서 원시 값을 제외한 나머지 값은 모두 객체다.
원시 타입은 하나의 값만을 나타내지만 객체 타입은 다양한 타입의 값(원시 값 또는 다른 객체)을 하나의 단위로 구성한 복합적인 자료구조다.

let user = { // 객체
name: "John", // 프로퍼티, 키: "name", 값: "John"
age: 30 // 프로퍼티, 키: "age", 값: 30
};

객체는 0개 이상의 프로퍼티로 구성된 집합, 프로퍼티는 키(key)와 값(value)으로 구성된다.
자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있고 함수도 일급 객체이므로 값으로 취급할 수 있다. 프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드(method)라고 부른다.

let user = {
name: "John",
age: 30
};
user.sayHi = function() {
alert("안녕하세요!");
};
user.sayHi(); // 안녕하세요!
  • 프로퍼티: 객체의 상태를 나타내는 값 (data)
  • 메서드: 프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작(behavior)

객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임객체 지향 프로그래밍이라고 한다.

객체 생성하기

자바스크립트는 다양한 객체 생성 방법을 지원한다.

객체 리터럴 외의 방법들은 모두 함수를 이용해 객체를 생성한다.

원시 값과 비교하기

원시 타입과 객체 타입의 다른점

  1. 원시 타입의 값, 원시 값은 불변 값(immutable value)이고 객체 타입의 값은 변경 가능 값(mutable value)이다.
  2. 원시 값을 변수에 할당하면 변수에는 실제 값이 저장되고 객체는 참조 값이 저장된다.
  3. 원시 값을 갖는 변수를 다른 변수에 할당하면 원시 값이 복사되어 전달(값에 의한 전달)되고 객체를 가리키는 변수를 다른 변수에 할당하면 원본 참조 값이 복사되어 전달(참조에 의한 전달)된다.

원시 값이란

  • 불변 값
    • 읽기 전용으로 바꿀 수 없다는 말 (변수가 아닌 값이)
    • 변경 불가능하기 때문에 데이터의 신뢰성을 보장
  • 변수에 할당할 때
    • 원시 값이 할당된 변수에 새로운 원시 값을 할당하려하면, 이미 저장된 원시 값을 변경하는 것이 아니라 새로운 메모리 공간을 확보한 뒤 재할당한 원시 값을 그곳에 저장하고 변수는 새롭게 재할당한 값을 가리키는 것
    • 변수가 참조하던 메모리 공간의 주소가 변경된 이유가 바로 원시 값이 변경 불가능한 값이기 때문이다.
  • 원시 값이 변경 가능한 값이라면 예기치 않게 변수 값이 변경될 수 있다는 것을 의미한다. → 값의 변경을 추적하기 어렵게 한다.
  • 문자열 타입은 원시 타입이다.
    • 문자열은 유사 배열 객체, 이터러블이기 때문에 배열과 유사하게 사용할 수 있다.
      • 하지만 원시 타입이기 때문에 배열처럼 문자 변경을 할 수 없다.
        let word = 'hello';
        word[0] = 'z';
        console.log(word); // hello

원시 타입의 값에 의한 전달 pass by value

let score = 100;
let copyScore = score;
console.log(score, copyScore); // 100 100
console.log(score === copyScore); // true
  • 변수(copyScore)에 원시 값을 갖는 변수(score)를 할당하면 할당받는 변수(copyScore)는 할당되는 변수(score)의 원시 값이 복사되어 전달된다. → 값에 의한 전달
  • 두 변수 다 100이라는 값을 갖지만 다른 메모리 공간에 저장된 별개의 값이다.
  • 값에 의한 전달이란 용어는 ECMAScript 사양엔 등장하지 않는다. → 다른 언어에서 많이 사용하는 용어
  • 또한 값이 전달되기 보다는 명확하게 표현하면 메모리 주소가 전달된다. 변수에는 값 그 자체가 저장되는 것이 아닌 메모리 주소가 저장되기 때문이다!
  • 더 명확히 표현하면 자바스크립트를 만드는 곳에 따라 내부 동작 방식이 다를 수 있다. ECMAScript 사양에 정의되어있지 않기 때문...
    • 변수에 변수를 할당할 때, 할당 시점에 두 변수가 기억하는 메모리 주소가 다를 수 있고,
    • 할당 시점에는 같은 메모리 주소를 기억하다가 한 변수가 재할당을 하면 새로운 메모리 공간에 재할당된 값을 저장할 수 있다.
  • 2가지 방식 모두 결국에는 두 변수의 원시 값은 한쪽에서 재할당을 통해 값이 변경되어도 서로 간섭할 수 없다는 것!

객체 타입의 참조에 의한 전달 pass by reference

  • 객체 타입의 값은 변경 가능한 값(mutable value)이다.
  • 원시 값을 할당한 변수의 경우, 변수가 기억하는 메모리 주소를 통해서 원시 값에 접근할 수 있지만, 객체는 할당한 변수가 기억하는 메모리 주소를 통해 참조 값에 접근할 수 있다.
    • 참조 값(reference value)이란, 생성된 객체가 저장된 메모리 공간의 주소이다.
      • 힙(heap)에 저장된 객체를 가리키는 포인터
  • 객체를 할당한 변수는 변수는 객체를 참조하고 있다. 변수는 객체를 가리키고 있다. 라고 표현한다.
  • 원시 값은 변경 불가능한 값이므로 변수 값을 변경하려면 재할당을 해야 하고, 객체는 재할당 없이 직접 변경이 가능하다.
let person = {
name: 'Lee Jung Seob'
};
// 프로퍼티 값 update
person.name = 'Edgar Degas';
// 프로퍼티의 값 생성하기
person.address = 'Paris';
  • 재할당을 한 것이 아니므로, 객체를 할당한 변수의 참조 값은 그대로다.
  • 객체는 크기가 매우 클 수도 있고 크기가 일정하지 않을 수도 있고, 프로퍼티가 객체일 수도 있어서 원시 값처럼 복사해서 새로 재할당 하는 것은 비용이 클 수 있다. → 비효율적인 것
    • 그래서 메모리를 효율적으로 사용하기 위해, 성능 향상을 위해 변경 가능한 값으로 설계된 것이다.

객체 복사에 대하여

객체를 프로퍼티로 갖는 객체를 복사할 때,

  • 얕은 복사: 한 단계까지만 복사
  • 깊은 복사: 객체에 중첩된 객체가지 모두 복사하는 것을 말한다.
  • 얕은 복사와 깊은 복사로 생성된 객체는 원본 객체와 다른 객체다. → 원본 객체와 참조 값이 다르다.
  • 얕은 복사는 객체에 중첩된 객체의 경우 참조 값을 복사하고, 깊은 복사는 중첩된 객체까지 모두 복사한다.
더 알아보기

참조에 의한 전달의 부작용

let person = {
name: 'Degas'
};
// 참조 값 복사하기 (얕은 복사)
let copyPerson = person;
  • personcopyPerson은 동일한 참조 값, 즉 동일한 객체를 가리킨다.
    • 두 식별자가 하나의 객체를 공유한다는 것
    • 한 변수가 객체를 변경하게 되면 둘 다 영향을 받는다.

결론

"값에 의한 전달", "참조에 의한 전달" 모두 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사한다는 점은 동일하다. 하지만 식별자가 기억하는 메모리 공간이 원시 값인지 참조 값인지가 다른 것 책에선 자바스크립트에는 "참조에 의한 전달"은 존재하지 않고 "값에 의한 전달"만 존재한다고 나와있었다. 매번 공부를 하며 C나 Java나 다른 언어에 있는 참조에 의한 전달이 JavaScript에도 있다고 생각하며 의식하고 살았는데 결론을 보니, 꼬여있던 생각의 실타래가 풀린듯한 기분이다.

더 알아보기

reference

Edit this page
Last updated on 8/13/2022