[코어 자바스크립트] 데이터 타입

김진서·2025년 4월 23일

우아한테크코스 7기

목록 보기
32/56
post-thumbnail

👉 ‘코어 자바스크립트’의 ‘01 데이터 타입’을 읽으며 기억할 내용들과 새로 알게 된 내용을 정리하였습니다.

🔽 1-1 데이터 타입의 종류


  • 기본형: Number, String, Boolean, null, undefined, Symbol
  • 참조형: Array, Function, Date, RegExp, Map, WeakMap, Set, WeakSet

할당과 연산 시

  • 기본형: 주소값을 바로 복제
  • 참조형: 주소값 묶음의 주소값 복제

🔽 1-2 데이터 타입에 관한 배경지식


메모리와 데이터

  • 비트: 0, 1을 표현할 수 있는 하나의 메모리 조각
  • 각 비트는 고유한 식별자로 위치를 확인.
  • 효율적으로 사용하기 위해 바이트 탄생.
  • 데이터 타입별로 메모리 영역을 2, 4 바이트 등으로 정의.
  • 모든 데이터는 메모리 주소값(바이트 단위의 식별자)으로 서로 구분하고 연결.

식별자와 변수

  • 변수: 변할 수 있는 데이터
  • 식별자: 변수명

🔽 1-3 변수 선언과 데이터 할당


변수 선언

  • 변수: 변경 가능한 데이터가 담길 수 있는 공간 or 그릇.
// 가변한 데이터, 식별자는 a.
var a;
주소 1003
데이터 이름: a
값: undefined

데이터 할당

var a;
a = 'abc';
    
var a = 'abc';  // 변수 선언 및 할당 한 문장 표현
변수 영역 주소 1003
변수 영역 데이터 이름: a
값: @5004
데이터 영역 주소 5004
데이터 영역 데이터 'abc'
  • 변수와 데이터를 분리하는 이유: 5를 500개 할당하는 게 아니라, 5 하나를 500개가 가리키게 하는 것.

🔽 1-4 기본형 데이터와 참조형 데이터


  • 불변값

    • 바꿀 수 있으면 변수, 바꿀 수 없으면 상수.
    • 변수와 상수를 구분 짓는 변경 가능성의 대상은 변수 영역 메모리.
    • 불변성 여부를 구분할 때의 변경 가능성 대상은 데이터 영역 메모리.
    • 즉, 불변값과 상수는 다르다.
    var a = 'abc';  // 'abc'가 'abcdef'로 바뀌는 게 아니라 새로 'abcdef'를 만들어 저장.
    a = a + 'def';  // 'abc'와 'abcdef'는 완전히 별개의 데이터.
    
    var b = 5;  // 5를 만들어 저장.
    var c = 5;  // b의 5를 재할당.
    b = 7;  // 5를 7로 바꾸는 게 아니라 기존의 7을 찾거나 새로 만들어서 저장.
    • 한 번 만들어진 값은 garbage collecting(메모리 수거)을 당하지 않는 한 변하지 않는다.
  • 가변값

    var obj1 = {
      a: 1,
      b: 'bbb'
    };
    변수 주소 1002
    영역 데이터 이름: obj1
    값: @5001
    데이터 주소 5001 5003 5004
    영역 데이터 @7103 ~ ? 1 ‘bbb’
    객체 @5001의 주소 7103
    변수 영역 데이터 이름: a
    값: @5003
    이름: b
    값: @5004
    • 기본형 데이터와 달리 객체의 변수(프로퍼티) 영역이 별도로 존재한다.
    • 변수 영역만 별도로 할당하였고, 데이터 영역은 기존의 공간 활용. 변수에는 다른 값 대입 가능.
    • 이 점 때문에 흔히 불변하지 않다(가변값이다)라고 함.
        var obj1 = {
        	a: 1,
        	b: 'bbb'
        };
        obj1.a = 2;
      변수 주소 1002
      영역 데이터 이름: obj1
      값: @5001

      불변
      데이터 주소 5001 5003 5004 5005
      영역 데이터 @7103 ~ ? 1 ‘bbb’ 2
      객체 @5001의 주소 7103
      변수 영역 데이터 이름: a
      값: @5005

      가변
      이름: b
      값: @5004
  • 변수 복사 비교

    ✅ 원시 타입은 값 자체가 복사되므로 독립적

    ✅ 참조 타입은 주소를 복사하므로, 복사본을 변경하면 원본도 영향을 받음

    ✅ 객체를 독립적으로 복사하려면 얕은 복사 또는 깊은 복사 필요

    ✅ 얕은 복사는 1단계만 복사, 깊은 복사는 모든 중첩 객체까지 복사

    💡 결론

    ✔ 원시 타입(number, string 등)은 값 복사

    ✔ 객체(object, array, function)는 참조 복사

    불필요한 참조 공유를 방지하려면 깊은 복사를 고려해야 함! 🚀

🔽 1-5 불변 객체


  • 불변 객체를 만드는 간단한 방법

    • 불변 객체(immutable object)는 최근 React, Vue, Angular 등의 라이브러리 프레임워크 뿐만 아니라, 함수형 프로그래밍, 디자인 패턴 등에서도 매우 중요.
    • 객체도 데이터 자체를 변경하고자 하면(새로운 데이터 할당) 기본형과 마찬가지로 기존 데이터는 변하지 않음. (불변성)
      • 내부 속성 변경 시 가변성.
    • 따라서, 내부 속성 변경시마다 매번 새로운 객체를 만들어 재할당을 하거나, 자동으로 새로운 객체를 만드는 도구를 활용하면 객체도 불변성을 확보.
      • ex) immutable.js, immmer js, immutability-helper 등의 라이브러리. ES6의 spread operator, Object.assign 메서드

    왜 불변 객체가 필요한가?

    • 값으로 전달받은 객체에 변경을 주더라도, 원본 객체는 변하지 않아야 하는 경우.

      var user = {
      	name: "Kim",
      	gender: "female"
      }
      
      var changeName = function(user, newName) {
      	var newUser = user;
      	newUser.name = newName;
      	return newUser;
      }
      
      var user2 = changeName(user, 'Jung');
      
      console.log(user.name, user2.name)  // Jung Jung
    • 위 예시처럼 user2 호출 시, 내부 프로퍼티만 변경함으로써 기존 user 객체를 동시에 변경(가변성)

    • user와 user2가 다른 값을 가질 수 있도록 하려면 아래와 같이 새로운 객체를 반환하도록 수정.

      var user = {
      	name: "Kim",
      	gender: "female"
      }
      
      var changeName = function(user, newName) {
      	return {
      		name: newName,
      		gender: user.gender
      	}
      }
      
      var user2 = changeName(user, 'Jung');
      
      console.log(user.name, user2.name)  // Kim Jung
    • 하지만, 변경된 코드의 경우 변경할 필요가 없는 기존 객체의 ‘gender’속성도 하드코딩으로 입력. 객체에 정보가 많을수록 비효율적인데, 프로퍼티 개수에 상관없이 모든 프로퍼티를 복사하는 함수를 만들 수 있음.

      // 얕은 복사
      var copyObject = function (target) {
      	var result = {};
      	for (var prop in target) {
      			result[prop] = target[prop]
      	}
      }
    • 물론 협업하는 모든 개발자들이 copyObject라는 얕은 복사를 사용하면 문제가 되지 않음. (= user 객체가 곧 불변 객체)

    • 하지만, 그 규칙을 지키지 않을 수도 있으므로 아예 프로퍼티를 변경할 수 없게 제약을 거는게 더 안전.

  • 얕은 복사와 깊은 복사

    • 얕은 복사(shallow copy): 바로 아래 단계의 값만 복사.

      • ex) 중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주소값만 복사.
      • 즉, 원본과 사본이 동일한 참조형 데이터 주소를 가리키므로 사본을 바꾸면 원본도 변경.
    • 깊은 복사(deep copy): 내부의 모든 값들을 하나하나 찾아서 전부 복사.

      • ex) 중첩된 객체에서 프로퍼티 내부의 값들까지 전부 복사. 재귀로 구현 가능.
      // 깊은 복사
      var copyObjectDeep = function(target) {
      	var result = {};
      	if (typeof target === 'object' && target !== null) {
      		for (var prop in target) {
      			result[prop] = copyObjectDeep(target[prop]);
      		}
      	} else {
      		result = target;
      	}
      	return result;
      }
    • target이 객체인 경우에는 내부 프로퍼티를 순회하며 copyObjectDeep 함수를 재귀적으로 호출하고, 객체가 아닌 경우에는 target을 그대로 지정.

    • 이 함수는 원본과 사본이 서로 완전히 다른 객체를 참조하게 하여 어느쪽의 프로퍼티를 변경하더라도 다른 쪽에 영향을 주지 않음.

🔽 1-6 undefinednull


  • undefined와 null은 자바스크립트에서 모두 ‘없음'을 의미. 하지만 미세한 차이점이 존재.

1. undefined

  • 자바스크립트 엔진은 사용자가 어떤 값을 지정할 것이라고 예상되는 상황임에도 실제로 그렇게 하지 않았을 때 undefined를 반환.
    • 1) 값을 대입하지 않은 변수. 즉, 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때
    • 2) 객체 내부의 존재하지 않는 프로퍼티에 접근하려고 할 때
    • 3) return 문이 없거나 호출되지 않는 함수의 실행 결과

2. null

  • null은 ‘비어있음'을 명시적으로 나타내고 싶을 때 사용.
  • typeof nullobject라고 반환되는데, 이는 자바스크립트 자체 버그. 따라서 변수의 값이 null인지 확인하려면 일치 연산자로 확인 필요.

undefinednull을 구분하기 위해서는 동등 연산자 대신, 일치 연산자(===)를 사용.

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
profile
PAy IT forwaRD를 실천하는 프론트엔드 개발자.

0개의 댓글