데이터 타입에 관한 고찰

string_main·2023년 3월 16일
0

JavaScript

목록 보기
22/22
post-thumbnail

🌱 기본형 데이터와 참조형 데이터


  • 객체의 프로퍼티를 변경했을 때
    var a = 10;
    var b = a;
    var obj1 = { c: 10, d: 'ddd' };
    var obj2 = obj1;
    
    b = 15;
    obj2.c = 20;
    기본형 데이터를 복사한 변수 b의 값을 바꿨을 때, 해당 데이터 참조 값(주소) 자체가 변경되는 반면, 참조형 데이터를 복사한 변수 obj2의 프로퍼티를 바꾸면 참조 값이 가리키는 객체의 프로퍼티가 저장된 곳의 참조 값이 바뀔 뿐, 변수의 참조 값 자체가 바뀌지 않는다. 즉, 변수 a와 b는 서로 다른 주소를 바라보게 됐으나, 변수 obj1와 obj2는 여전히 같은 객체를 바라보고 있는 상태이다. 이를 코드로 표현하면 아래와 같다.
    a !== b
    obj1 === obj2
    이 결과가 기본형 데이터와 참조형 데이터의 가장 큰 차이점이다. 대부분의 자바스크립트 책에서 기본형은 값을 복사하고 참조형은 주솟값을 복사한다고 설명하고 있지만, 실은 어떤 데이터 타입이든 변수에 할당하기 위해서는 주솟값을 복사해야 한다. 엄밀히 따지면 자바스크립트의 모든 데이터 타입은 참조형 데이터일 수밖에 없다. 다만, 기본형은 주솟값 복사 과정이 한 번만 이뤄지고, 참조형은 한 단계를 더 거치게 된다는 차이가 있을 뿐이다.
  • 객체 자체를 변경했을 때
    var a = 10;
    var b = a;
    var obj1 = { c: 10, d: 'ddd' };
    var obj2 = obj1;
    
    b = 15;
    obj2 = { c: 20, d: 'ddd' };
    a !== b
    obj1 !== obj2
    이 경우에는 값을 직접 변경했기 때문에 객체에 대한 변경임에도 값이 달라졌다. 즉, 참조형 데이터가 가변값이라고 설명할 때는 참조형 데이터 자체를 변경할 때가 아니라 객체 내부의 프로퍼티를 변경할 때만 성립한다.

🌱 불변 객체


  • 객체의 내부 프로퍼티를 변경할 일이 있을 때마다 새로운 객체를 만들어 재할당하기로 하거나 자동으로 새로운 객체를 만드는 도구(라이브러리, Spread 연산자, Object.assign 메서드 등)를 활용하면 객체의 불변성을 확보할 수 있다.
  • 객체에 변경을 가하더라도 원본 객체는 변하지 않아야 하는 경우에 불변 객체가 필요하다.
    // 객체의 가변성에 따른 문제점
    
    var user = {
      name: 'Jaenam',
      gender: 'male',
    };
    
    var changeName = function(user, newName) {
      var newUser = user;
      newUser.name = newName;
      return newUser;
    };
    
    var user2 = changeName(user, 'Jung');
    
    if (user !== user2) {
      console.log('유저 정보가 변경되었습니다.'); // 출력되지 않는 문제 발생
    }
    console.log(user.name, user2.name); // Jung Jung
    console.log(user === user2); // true
    // 해결된 코드
    
    var user = {
      name: 'Jaenam',
      gender: 'male',
    };
    
    var changeName = function(user, newName) {
      return {
        name: newName,
        gender: user.gender, // 변경할 필요없는 기존 정보가 하드 코딩된 문제점
      };
    };
    
    var user2 = changeName(user, 'Jung');
    
    if (user !== user2) {
      console.log('유저 정보가 변경되었습니다.'); // 유저 정보가 변경되었습니다.
    }
    console.log(user.name, user2.name); // Jaenam Jung
    console.log(user === user2); // false
    // 좀 더 개선된 코드 (얕은 복사)
    
    var copyObject = function(target) {
      var result = {};
      for (var prop in target) {
        result[prop] = target[prop];
      }
      return result;
    };
    
    var user = {
      name: 'Jaenam',
      gender: 'male',
    };
    
    var user2 = copyObject(user);
    user2.name = 'Jung';
    
    if (user !== user2) {
      console.log('유저 정보가 변경되었습니다.'); // 유저 정보가 변경되었습니다.
    }
    console.log(user.name, user2.name); // Jaenam Jung
    console.log(user === user2); // false
    1-14

🌱 undefined와 null


  • undefined : 사용자가 명시적으로 지정할 수도 있지만, 값이 존재하지 않을 때 자바스크립트 엔진이 자동으로 부여할 때도 있다. (사용자가 어떤 값을 지정할 것이라 예상되는 상황임에도 실제로는 그렇게 하지 않았을 때) ‘비어있음’을 의미하는 순회 가능한 하나의 값이다.
    • 값을 대입하지 않은 변수, 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때

      • 배열에 대해서는 다소 특이한 동작을 확인할 수 있다.
        // 비어있는 요소와 undefined를 할당한 요소는 다르다.
        // 비어있는 요소는 순회 대상에서 제외된다.
        
        var arr1 = [];
        arr1.length = 3;
        console.log(arr1); // [empty x 3]
        
        var arr2 = new Array(3);
        console.log(arr2); // [empty x 3]
        
        var arr3 = [undefined, undefined, undefined];
        console.log(arr3); // [undefined, undefined, undefined]
    • 객체 내부의 존재하지 않는 프로퍼티에 접근하려 할 때

    • return 문이 없거나 호출되지 않는 함수의 실행 결과

      💡 값으로써 할당된 undefined는 실존하는 데이터인 반면, 자바스크립트 엔진이 반환해주는 undefined는 문자 그대로 값이 없음을 나타낸다. 이러한 혼란을 방지하기 위해 undefined는 오직 자바스크립트 엔진이 반환하는 경우로 한정되게 하면 된다. 즉, 같은 의미를 가진 null을 사용해 직접 undefined를 할당하지 않게 해주면 된다.
  • null : 사용자가 명시적으로 ‘없음’을 표현하기 위해 대입한 값.
    // 일치 연산자(===)를 사용해야만 null을 정확히 판별할 수 있다.
    
    var n = null;
    console.log(typeof n); // object
    
    console.log(n == undefined); // true
    console.log(n == null); // true
    
    console.log(n === undefined); // false
    console.log(n === null); // true
    💡 typeof 명령어는 null에 대해서 object를 반환하는 버그가 있다.

🌿 알게된 점 & 느낀 점


엄밀히 따지면 자바스크립트의 모든 데이터 타입은 참조형 데이터라는 것과 기본형 데이터와 참조형 데이터가 메모리에 할당되는 과정이 다르기 때문에 동작 방식에서 차이가 나타나는 것이라는 사실을 알게되었고, 참조형 데이터가 가변값이라고 설명할 때는 참조형 데이터 자체를 변경할 때가 아니라 객체 내부의 프로퍼티를 변경할 때만 성립한다는 부분과 객체의 불변성을 유지해야 하는 상황이 어떤 상황인지 알게 되었다.

| 참고자료 |

코어 자바스크립트

profile
FE developer

0개의 댓글