개발일지/TIL(Today I Learned)

2024-11-05

프린스 알리 2024. 11. 5.

내일배움캠프 Node.js 트랙 7일차

1. ZEP에서 이루어진 자바 문법 스터디

가변성과 불변성

자바스크립트의 변수는 크게 기본 자료형(원시형Primitive Types)과 참조 자료형(Reference Types)으로 분류된다. 참조 데이터 타입은 데이터의 집합으로, 배열이나 객체가 대표적이다. 고정된 크기를 가지지 않고, 주소만을 가지기 때문에 동적으로 크기가 변하는 데이터를 보관할 수 있다.

기본형과 참조형의 구분 기준

  1. 복제의 방식
    a. 기본형 : 값이 담긴 주소값을 바로 복제
    b. 참조형 : 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제

  2. 불변성의 여부
    a. 기본형 : 불변성을 띔
    b. 참조형 : 불변성을 띄지 않음

(1) 기본형 데이터의 할당

var str;
str = 'test!';

 

 

(2) 참조형 데이터의 할당

// 참조형 데이터는 별도 저장공간(obj1을 위한 별도 공간)이 필요합니다!
var obj1 = {
    a: 1,
    b: 'bbb,
};

 

var obj1 = {
    a: 1,
    b: 'bbb',
};
// 데이터를 변경해봅시다.
obj1.a = 2;

 

 

데이터 영역에 저장된 값은 여전히 계속 불변값이지만, obj1을 위한 별도 영역은 얼마든지 변경이 가능하다. 때문에 참조형 데이터를 흔히, ‘불변하지 않다(=가변하다)’ 라고 한다.

 

(3) 데이터의 복사 후 변경

데이터 복사

// STEP01. 쭉 선언을 먼저 해볼께요.
var a = 10; //기본형
var obj1 = { c: 10, d: 'ddd' }; //참조형
// STEP02. 복사를 수행해볼께요.
var b = a; //기본형
var obj2 = obj1; //참조형

 

 

데이터 변경

// STEP01. 쭉 선언을 먼저 해볼께요.
var a = 10; //기본형
var obj1 = { c: 10, d: 'ddd' }; //참조형
// STEP02. 복사를 수행해볼께요.
var b = a; //기본형
var obj2 = obj1; //참조형
// STEP03. 복사한 값을 변경하기
b = 15;
obj2.c = 20;

 

 

보다시피 원본 객체까지 변경되는 현상이 발생했다. (→ 원하지 않은 결과)
만약, 객체의 프로퍼티(=속성)에 접근해서 값을 변경하는 것이 아니라 객체 자체를 변경하는 방식으로 값을 바꾼다면 어떨까? (이 때에는 obj2를 위한 메모리 영역이 하나 더 필요하다.)

//기본형 데이터
var a = 10;
var b = a;
//참조형 데이터
var obj1 = { c: 10, d: 'ddd' };
var obj2 = obj1;
b = 15;
obj2 = { c: 20, d: 'aaa'};

 

이 경우엔 데이터 메모리 영역 자체가 달라져서 원본 객체(obj1)에 영향을 끼치지 않는다.
따라서, 참조형 데이터가 가진 가변성은 데이터 자체를 변경할 경우가 아니라, 그 내부의 프로퍼티를 변경할 때 성
립한다.

그렇다면 데이터 자체를 변경하는 게 정답일까?

그러나 이 방식엔 문제가 있다. 프로퍼티가 여러 개일 경우 일일이 하드코딩을 해줘야 한다는 점이다. 비효율적이고 가독성도 좋지 못하다. 원본 객체의 값을 불변하게 만들려면 대체 어떡해야 하는 걸까. 이때 처음 떠올릴 수 있는 게 얕은 복사 방식이다.

얕은 복사

말 그대로 프로퍼티를 하나하나 복사하여 별도의 메모리 영역에서 값을 변경하게끔 만들 수 있다. 방식은 여러 가지다. 이전 블로그 글에도 게시했듯 Object.assign()메소드나 전개구문으로도 객체의 얕은 복사를 수행할 수 있다.
2024-11-04

 

2024-11-04

내일배움캠프 Node.js 트랙 4일차1. ZEP에서 이루어진 팀단위 프로젝트객체를 복사하고 병합하는 방식 - Object.assign과 전개 구문객체를 복사하고 병합하는 방법에 대해 알아보자 (이 글에서는 편의

princeali.tistory.com

이번에는 보다 직관적인 방식으로 얕은 복사를 해보도록 하겠다.

// for ~ in 구문을 이용하여, 객체의 모든 프로퍼티에 접근할 수 있다.
var copyObject = function (target) {
    var result = {};
    for (var prop in target) {
    result[prop] = target[prop];
    }
    return result;
}

이 copyObject() 함수로 복사를 한 다음, 복사를 완료한 객체의 프로퍼티를 변경하면 원본 객체의 값을 보존할 수 있을 것이다. 다만 이 방식도 완벽하진 않다. 중첩된 객체에 대해서는 완벽한 복사를 할 수 없기 때문이다. 그래서 이 다음으로 떠올려야 하는 해법이 바로 깊은 복사이다.

깊은 복사

객체의 프로퍼티 중, 기본형 데이터는 그대로 복사 + 참조형 데이터는 다시 그 내부의 프로퍼티를 복사 ⇒ 재귀적 수행!

var copyObjectDeep = function(target) {
    var result = {};

    if (typeof target === 'object' && target !== null) {
        for (var prop in target) {
            result[pop] = copyObjectDeep(target[prop]); // 내부의 프로퍼티를 복사
        }
    } else {
        result = target; // 기본형 데이터는 그대로 복사
    }
    return result;
}

'개발일지 > TIL(Today I Learned)' 카테고리의 다른 글

2024-11-07  (4) 2024.11.07
2024-11-06  (0) 2024.11.06
2024-11-04  (0) 2024.11.04
2024-11-01  (3) 2024.11.01
2024-10-31  (2) 2024.10.31

댓글