11 원시 값과 객체의 비교

이재철·2021년 8월 29일
0

javaScript

목록 보기
3/19

  • 원시 타입 : 데이터 타입(문자열, 숫자, 불리언, null, undefined, 심벌, 객체 타입)
  • 객체 타입 : object, reference type

원시 값

  • 원시 값은 변경 불가능한 값(immutable value) 즉 읽기 전용 값
  • "원시 값은 변경 불가능하다"는 원시 값 자체를 변경할 수 없다는 것이며,
    변수 값을 변경할 수 없다는 뜻은 아니다.
  • 변수는 언제든지 재할당을 통해 변수 값을 변경 가능
const o = {}; // const 키워드의 변수는 재할당이 금지. 상수는 재할당이 금지된 변수
// const 키워드를 사용한 변수에 할당한 원시 값(상수)는 변경 불가능
// const 키워드를 사용해 선언한 변수에는 할당한 객체는 변경가능
o.a = 1; // {a: 1}

원시값은 변경 불가능한 값이다
  • 불변성 : 변수 값을 변경하기 위해 원시 값을 재할당, 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 후, 변수가 참조하던 메모리 공간의 주소를 변경

문자열과 불변성

  • 원시 값인 문자열은 0개 이상의 문자로 이루워진 집합이며, 1개의 문자는 2바이트의 메모리 공간에 저장됨
  • 자바스크립트의 문자열은 원시 타입이며, 변경 불가능
  • 문자열이 생성된 이후에는 변경할 수 없음을 의미함
  • 문자열은 유사 배열 객체이며 이터러블이므로 배열과 유사하게 접근 가능
var str1 = ''; // 0개의 문자로 이루어진 문자열 (빈 문자열)
var str2 = 'Hello'; // 5개의 문자로 이루어진 문자열

유사 배열 객체(array-like object)

var str = 'string'
console.log(str[0]); // s
console.log(str.length); // 6
console.log(str.toUpperCase()); // STRING
var str1 = 'string';
// 문자열은 유사 배열이므로 배열과 유사하게 인덱스를 사용해 접근가능
// 하지만 문자열은 원시 값이므로 변경 불가능 (에러발생x)
str[0] = 'S';
console.log(str1); // string

값에 의한 전달

var score = 80;
var copy = score;

score = 100;
console.log(score); // 100
console.log(copy); // 80
  • 값에 의한 전달 : 변수에 원시 값을 갖는 변수를 할당하려면 할당받는 변수에는 할당되는 변수의 원시값이 복사되어 전달됨
var score = 80;
var copy = score;

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

// score 변수의 값을 변경해도 copy 변수의 값에는 어떤 영향을 미치지 않음
score = 100;
console.log(score === copy); // false

score 변수와 copy 변수는 숫자 값 80을 갖는다는 점은 동일하지만
"다른 메모리 공간에 저장된 별개의 값"


객체

  • 객체는 프로퍼티의 개수가 정해져 있지 않으며, 동적으로 추가 삭제가 가능함
  • 객체(참조) 타입의 값, 객체는 변경 가능한 값(mutable value)
  • 프로퍼티의 값에 제약이 없으며 원시 값과 같이 확보해야 할 메모리 공간의 크기를 사전에 정할 수 있음
var person = {
  name: 'Lee'
};
// person 변수에 저장되어 있는 참조 값으로 실제 객체에 접근
console.log(person); // {name:' "Lee"}
  • 원시 값을 할당한 변수는 원시 값 자체를 값으로 갖음
  • 객체를 할당한 변수가 기억하는 메모리주소를 통해 메모리 공간에 접근하면 참조 값(reference value)에 접근 가능함
  • 참조 값은 생성된 객체가 저장된 메모리 공간 주소 그 자체

얕은 복사(shallow copy)와 깊은 복사(deep copy)

const o = { x: { y: 1 } };
// 얕은 복사
const c1 = { ...o }; 
console.log(c1 === o); // false
console.log(c1.x === o.x); // true
// 깊은 복사
const _ = require('lodash');
const c2 = _.cloneDeep(o);
console.log(c2 === o); // false
console.log(c2.x === o.x); // false
  • 얕은 복사와 깊은 복사로 생성된 객체는 원본과 다른 객체 -> 참조 값이 다른 별개의 객체
  • 얕은 복사 : 객체에 중첩되어 있는 개체의 경우 참조 값을 복사
  • 깊은 복사 : 객체에 중첩되어 있는 객체까지 모두 복사해서 원시 값처럼 완전한 복사본 생성
const v = 1;
// 깊은 복사
const c1 = v;
console.log(c1 === v); // true
const o = { x: 1 };
// 얕은 복사
const c2 = o;
console.log(c2 === o); // true;

참조에 의한 전달

참조에 의한 전달 : 원본의 참조 값이 복사되어 전달되는 것

두 개의 식별자가 하나의 객체를 공유

  • 메모리 주소는 다르지만 동일한 참조 값을 갖는 경우 동일한 객체를 가르키게 됨
  • 원본 또는 사본 중 어느 한쪽에서 객체를 변경(프로퍼티 추가, 삭제)하는 경우 서로 영향을 주고 받음

ver person = {
 name: 'Lee'
};
// 참조 값 복사(얕은 복사)
var copy = person;
console.log(copy === person); // true

copy.name = 'Kim';
person.address = 'Seoul';

// copy와 person은 동일한 객체를 가르키므로 서로 영향을 주고 받음
console.log(person); // {name: "Kim", address: "Seoul"};
console.log(copy); // {name: "Kim", address: "Seoul"};

"값에 의한 전달"과 "참조에 의한 전달"은 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달하는 면은 동일
하지만 자바스크립트는 "값에 의한 전달" 만이 존재한다고 말할 수 있음

var person1 = {
 name: 'Lee'
};
var person2 = {
 name: 'Lee'
};
var person3 = {
 name: 'Kim'
}

// 객체는 내용은 같지만 다른 메모리에 저장된 별개의 객체 (참조 값은 다른 값)
console.log(person1 === person2); // false;
// 두 표현식 모두 원시 값 'Lee' 평가
console.log(person1.name === person2.name); // true;
console.log(person1.name === person3.name); // false;


📖 참고도서 : 모던 자바스크립트 Deep Dive 자바스크립트의 기본 개념과 동작 원리 / 이웅모 저 | 위키북스

profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글