• 데이터 불변성

    2022. 9. 2.

    by. JJo 😊

    📌 원시 데이터 : 변경이 불가능한 값

    메모리 영역에서의 변경은 불가능하며, 새로운 값을 만들때 메모리에 같은 값이 있으면 이미 만들어진 메모리 주소의 값을 바라보지만, 새로운 값일 경우 새로운 메모리에 할당한다.

     String, Number, Boolean, undefined, null 

    let str = 'Hello';
    str = 'world';

    첫번째 구문이 실행되면 메모리에 문자열 'Hello' 가 생성되고, 변수 str은 'Hello'의 메모리 주소를 가리킨다. 두번째 구문이 실행되면 이전에 생성된 'Hello'를 수정하는 것이 아니라 새로운 메모리에 새로운 문자열 'World'를 생성하고 변수 str은 이를 가리킨다. 따라서 메모리에는 'Hello'와 'World' 모두 존재하고 있으며, 변수 str은 처음에 'Hello'를 가리키고 있다가 'World'를 가리키도록 변경된 것이다.

    let statement = 'I am an immutable value'; // string은 immutable value
    let otherStr = statement.slice(8, 17);
    
    console.log(otherStr);   // 'immutable'
    console.log(statement);  // 'I am an immutable value'

    두번째 구문의 .slice( )메서드는 변수 statement 에 저장된 문자열을 변경하는 것이 아니라, 새로운 문자열을 생성하여 반환한다.

    📌 참조형 데이터 : 변경이 가능한 값

    메모리상에서 변경이 가능하며, 새로운 값을 만들 때마다 새로운 메모리 주소에 할당된다.(같은 값이어도 새로운 메모리에 할당한다.)

    Object, Array, Function 

    let a = {k: 1}
    let b = {k: 1}
    console.log(a, b, a===b); // {k: 1} {k: 1} false

    언뜻 모양만 보면 같은 값으로 보이지만 다른 메모리 주소에 할당이 되므로 일치 연산자로 비교하면 false값이 출력된다.

    let a = {k: 1}
    let b = {k: 1}
    a.k = 7;
    b = a; 
    console.log(a, b, a===b); // {k: 7} {k: 7} true
    a,k = 2;
    console.log(a, b, a===b); // {k: 2} {k: 2} true

    a, b가 서로 같은 메모리 주소의 객체를 바라보게 되었으므로 a와 b는 서로 같은 값을 공유하게 되고, 한쪽에서 해당 값을 수정해도 같은 메모리를 바라보고 있으므로 다른 쪽에서도 변경된 값을 참조하게 된다.

    이러한 현상이 의도된 경우라면 문제가 없지만, 의도하지 않은 부분이라면 문제가 될 수 있다. 그래서 이런 문제를 해결하기 위해서는 '복사'라는 개념을 이해하고 사용하여야 한다.

    📌 얕은 복사와 깊은 복사

    얕은 복사는 겉표면만 복사하는 개념이고, 깊은 복사는 그 안의 데이터 모두 복사하는 개념이다.

    👀 Object.assign( )

    Object.assign()은 타겟 객체로 출처 객체의 프로퍼티를 복사한다. 이때, 출처 객체의 프로퍼티와 동일한 프로퍼티를 가진 타겟의 프로퍼티는 출처 객체의 프로퍼티로 덮어쓰기 된다.

    const user = {
    	nmae: 'eunhye',
    	age: 29,
    	email: ['eunhye919@gmail.com']
    }
    
    const copyUser = Object.assign({}, user); // Object.assign(타켓/대상객체, 출처객체);
    console.log(copyUser === user) // false
    
    user.age = 30;
    console.log(user.age); // 30
    console.log(copyUser.age) // 29

    👀 전개연산자

    const user = {
    	nmae: 'eunhye',
    	age: 29,
    	email: ['eunhye919@gmail.com']
    }
    const copyUser = {...user}
    console.log(copyUser === user) // false
    
    user.age = 30;
    console.log(user.age); // 30
    console.log(copyUser.age) // 29

    위의 내용들은 모두 얕은 복사에 해당한다. 얕은 복사는 원시데이터만 복사되고 그 안의 배열이나 객체와 같은 참조형 데이터는 여전히 같은 메모리를 바라보는 것이다.

    const user = {
    	nmae: 'eunhye',
    	age: 29,
    	email: ['eunhye919@gmail.com']
    }
    const copyUser = {...user}
    user.email.push('masimel@naver.com');
    console.log(user.email === copyUser.email); // true

    👀 lodash package 사용

    lodash package에서 제공하는 .cloneDeep( ) 메서드를 사용하여 깊은 복사를 할 수 있다.

    const user = {
    	nmae: 'eunhye',
    	age: 29,
    	email: ['eunhye919@gmail.com']
    }
    const copyUser = _.cloneDeep(user);
    user.email.push('masimel@naver.com');
    console.log(user.email === copyUser.email); // false

    참고 사이트

    https://poiemaweb.com/js-immutability

     

    Immutability | PoiemaWeb

    함수형 프로그래밍의 핵심 원리이다. 객체는 참조(reference) 형태로 전달하고 전달 받는다. 객체가 참조를 통해 공유되어 있다면 그 상태가 언제든지 변경될 수 있기 때문에 문제가 될 가능성도

    poiemaweb.com

     

    728x90

    'Javascript' 카테고리의 다른 글

    데이터 불변성  (0) 2022.09.10
    JS 프로처럼 쓰는 팁  (0) 2022.09.05
    DOMContentLoaded VS load  (0) 2022.09.02
    ES6 Classes  (0) 2022.09.01
    전개연산자  (0) 2022.08.28

    댓글