Languages/JavaScript

[HUFS/GnuVil] #4 객체 리터럴, 원시 값과 객체의 비교

성중 2022. 9. 20. 15:31

객체 리터럴

자바스크립트는 객체 기반의 프로그래밍 언어이며, 원시 값을 제외한 나머지 값 (함수, 배열, 정규 표현식 등)은 모두 객체이다. 또한 원시 값은 변경 불가능(immutable)한 값이지만 객체는 변경 가능(mutable)한 값이다

 

객체의 프로퍼티와 메서드

  • 프로퍼티: 객체의 상태를 나타내는 값(data)
  • 메서드: 프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작(behavior)

 

var person = {
  name: 'Lee'
};

// 마침표 표기법에 의한 프로퍼티 접근
console.log(person.name); // Lee

// 대괄호 표기법에 의한 프로퍼티 접근
console.log(person['name']); // Lee

프로퍼티는 두 가지 방법으로 접근할 수 있다

* 대괄호 표기법의 경우 키는 반드시 문자열이어야 한다

 

var person = {
  name: 'Lee'
};

console.log(person.age); // undefined

객체에 존재하는 않는 프로퍼티에 접근하면 레퍼런스 에러가 아닌 undefined를 반환한다

 

// ES6
let x = 1, y = 2;

// 프로퍼티 축약 표현
const obj = { x, y };

console.log(obj); // {x: 1, y: 2}

const obj = {
  name: 'Lee',
  // 메서드 축약 표현
  sayHi() {
    console.log('Hi! ' + this.name);
  }
};

obj.sayHi(); // Hi! Lee

ES6 이후 객체 내부에 프로퍼티, 메서드를 축약할 수 있다

* 다만 메서드는 축약할 경우 프로토타입이 없어 생성자 함수로 사용할 수 없다!

 

원시 값과 객체의 비교

 자바스크립트의 원시 값(primitive)객체가 아니면서 메서드도 가지지 않는 데이터이다

* string, number, bigint, boolean, undefined, symbol, null 7종류가 존재

 

var str = 'string';

// 문자열은 유사 배열이므로 배열과 유사하게 인덱스를 사용해 각 문자에 접근할 수 있다.
// 하지만 문자열은 원시값이므로 변경할 수 없다. 이때 에러가 발생하지 않는다.
str[0] = 'S';

console.log(str); // string

자바스크립트 문자열은 기본적으로 변경할 수 없다 (재할당은 메모리 주소의 변경)

 

var str = 'string';

// 문자열은 유사 배열이므로 배열과 유사하게 인덱스를 사용해 각 문자에 접근할 수 있다.
console.log(str[0]); // s

// 원시 값인 문자열이 객체처럼 동작한다.
console.log(str.length); // 6
console.log(str.toUpperCase()); // STRING

다만 문자열은 length 값을 가지며 인덱스로 문자에 접근할 수 있는 유사 배열 객체이다

 

var score = 80;

// copy 변수에는 score 변수의 값 80이 복사되어 할당된다.
var copy = score;

console.log(score, copy);    // 80  80
console.log(score === copy); // true

// score 변수와 copy 변수의 값은 다른 메모리 공간에 저장된 별개의 값이다.
// 따라서 score 변수의 값을 변경해도 copy 변수의 값에는 어떠한 영향도 주지 않는다.
score = 100;

console.log(score, copy);    // 100  80
console.log(score === copy); // false

값에 의해 전달된 값은 다른 메모리 공간에 저장된 별개의 값이다

 

엄밀히 표현하면 값의 전달이 아닌 메모리 주소의 전달

// const 키워드를 사용해 선언한 변수는 재할당이 금지된다. 상수는 재할당이 금지된 변수일 뿐이다.
const o = {};

// const 키워드를 사용해 선언한 변수에 할당한 원시값(상수)은 변경할 수 없다.
// 하지만 const 키워드를 사용해 선언한 변수에 할당한 객체는 변경할 수 있다.
o.a = 1;
console.log(o); // {a: 1}

원시 값은 변경할 수 없는 상수지만 객체의 프로퍼티는 재할당이 가능하다

 

객체는 프로퍼티 키를 인덱스로 사용하는 해시 테이블
객체를 변수에 할당하고 프로퍼티를 변경하는 경우

객체는 프로퍼티 할당을 위해 한 단계를 더 거치기 때문에 내부적으로 변경 가능한 값이다

* 불변 객체: Object.freeze()가 아닌 객체를 깊은 복사하고 프로퍼티를 변경한 후 바꿔 치는 기법을 의미

 

var person = {
  name: 'Lee'
};

// 참조값을 복사(얕은 복사). copy와 person은 동일한 참조값을 갖는다.
var copy = person;

// copy와 person은 동일한 객체를 참조한다.
console.log(copy === person); // true

// copy를 통해 객체를 변경한다.
copy.name = 'Kim';

// person을 통해 객체를 변경한다.
person.address = 'Seoul';

// copy와 person은 동일한 객체를 가리킨다.
// 따라서 어느 한쪽에서 객체를 변경하면 서로 영향을 주고 받는다.
console.log(person); // {name: "Kim", address: "Seoul"}
console.log(copy);   // {name: "Kim", address: "Seoul"}

얕은 복사(1단계만 복사) ~ 깊은 복사(재귀적으로 원시 값까지 전부 복사)

 

var person1 = {
  name: 'Lee'
};

var person2 = {
  name: 'Lee'
};

console.log(person1 === person2); // false
console.log(person1.name === person2.name); // true

즉, 자바스크립트에는 참조에 의한 전달은 존재하지 않고 값에 의한 전달만이 존재한다

 

Reference🔽

 

자바스크립트에서 참조에 의한 전달은 없다 (NONO!)

이 글은 모던자바스크립트 딥다이브라는 책에서 상당 부분 발췌했습니다. 자바스크립트를 공부하고자 하는 학생이라고 한다면 값에 의한 전달(pass by value)과 참조에 의한 전달(pass by reference)에

basemenks.tistory.com

 

 내용은 위키북스의 '모던 자바스크립트 Deep Dive' 바탕으로 작성되었습니다.