코어자바스크립트 1장<데이터 타입>

김정현·2021년 1월 5일
0
post-thumbnail

1. 데이터타입 종류

1-1) 기본형

  • 숫자(Number)
  • 불리언(Boolean)
  • Undefined
  • Null
  • 문자열(String)
  • Symbol (ES6에 추가 됨)

1-2) 참조형

객체(Object)

  • 배열(Array)
  • 날짜(Date)
  • Map, WeakMap (ES6에 추가 됨)
  • 함수(Function)
  • 정규식(RegExp)
  • Set, WeakSet (ES6에 추가 됨)

기본형 vs 참조형

  • 기본형은 값이 담긴 주소값을 바로복제.
  • 참조형은 값이담긴 주솟값들로 이루어진 묶음을 가리키는 주소값을 복제.
  • 기본형은 불변성(Immunitability)을 가지게 된다.

2. 데이터 타입에 관한 배경지식

2-1) 변수와 식별자

  • 변수와 식별자를 혼용해서 쓰지만, 이는 엄연히 다르다.
  • 변수란 변할 수 있는 수이다.
  • 식별자란 데이터를 식별하는데 사용하는 이름 즉 변수명이다.

3. 변수 선언과 데이터 할당

3-1) 변수 선언

let a;

변할 수 있는 데이터를 만든다, 이 데이터의 식별자는 a로 한다.

3-2) 데이터할당

let a; // 변수선언
a = 'abc'; // 데이터 할당

let = 'abc' // 한문장으로 표현

  1. 변수 영역에서 빈공간 (@1002) 확보
  2. 확보한 공간의 식별자를 a로 지정
  3. 데이터 영역의 빈공간(@5004)에 문자열 'abc'를 지정
  4. 변수 영역에서 a라는 식별자를 검색한다(@1002)
  5. 앞서 저장한 문자열의 주소(@5004)를 @1002의 공간에 대입한다.

3-3)데이터변환

let a = 'abc';
a = 'abcdef';

  • 위와 같이 'abc'가 할당된 공간을 고치지 않고 새로운 주소에 'abcdef'라는 문자열을 다시 할당.
    @5004의 데이터는 더이상 참조되지 않는다면 gc가 일어날때 수집대상이 될 것이다.

4. 기본형 데이터와 참조형 데이터

4-1) 불변값 (Immutable Value)

  • 변수와 상수를 구분하는 성질은 '변경 가능성' 이다.
  • 변수와 상수를 구분 짓는 요소 : 변수 영역 메모리의 변경 가능성
  • 불변성 여부를 구분 짓는 요소 : 데이터 영역 메모리의 변경 가능성
  • number, string, bollean, null, undefined, Symbol은 모두 불변값

4-2) 가변값 (Mutable Value)

기본형 데이터는 모두 불변값 이지만, 참조형의 경우 기본적인 성질은 가변값이지만,
설정에 따라 변경 불가능한 경우도 있다.(Object.defineProperty, Object.freeze 등)

4-2.1) 가변값 참조형 데이터의 할당

let obj1 = {
  a: 1,
  b: 'bbb'
};

  1. 컴퓨터는 메모리의 빈공간 (@1002)에 obj1이름을 저장한다.
  2. 임의의 데이터 저장공간 (@5001)에 데이터를 저장하려고보니, 여러개의 프로퍼티를 가진 데이터 그룹이다. 내부의 프로퍼티를 저장하기 위해 변수영역을 마련하고, 그 의 주소 (@7013 ~ ? ) 를 @5001에 저장한다.
  3. @7103 및 @7104에 각각 a와 b 프로퍼티 이름을 저장.
  4. 데이터영역에서 숫자1과 숫자 'bbb'를 검색 한 뒤, 그의 주소를 각각의 프로퍼티에 저장.

4-2.2) 가변값 참조형 데이터의 프로퍼티 재할당

var obj1 = {
 a: 1,
 b: 'bbb'
};
obj1.a = 2;

  1. obj1의 저장 된 메모리(@5001)의 값에는 변화가 없음
  2. obj1의 프로퍼티 a가 저장 된 주소(@7103) 값을 숫자 2가 저장 된 메모리 주소(@5005)로 교체

4-2.3)가변값 중첩 된 참조형 데이터(객체)의 프로퍼티 할당

var obj1 = {
 x: 3,
 arr: [3,4,5]
};

  1. 위와 같은 메모리 구조를 가지면, 참조형 변수 obj1의 property x,arr의 변수가 데이터영역의 @5003,@5004를 가리킨다
  2. x는 데이터를 바로 가리키므로 1이 저장된 @5003을 가리키나, arr은 배열(참조형) 변수를 가리키므로 데이터영역 내 @5004에는 주소값이 저장되어 있다.
  3. 배열의 property 0,1,2를 가리키는 @8104 ~ ? 주소로 가보면 다시 데이터영역의 number형의 주소가 저장되있으며 이를 각각 가리키게된다.

4-2.4)가변값 - 중첩 된 참조형 데이터(객체)의 프로퍼티 재할당

let obj = {
  x: 3,
  arr: [ 3, 4, 5]
};
obj.arr = 'str';

  1. obj.arr 프로퍼티의 메모리(@7104) 값은 문자열 'str'이 저장 된 메모리 주소(@5006)으로 교체
  2. 객체 [3, 4, 5] 를 위해 사용되었던 메모리 (@5003, @8104 ~)는 GC(가비지 컬렉터)의 수거 대상이 됨

5. 불변객체

5-1) 객체의 가변성 <-> 불변객체

  • 불변 객체는 React.js, Vue.js, Angular.js 뿐만 아니라 함수형 프로그램, 디자인 패턴에서도 등장하는 중요한 기초 개념
  • 참조형 데이터의 '가변'은 데이터 자체가 아니라 내부 프로퍼티를 변경할 때 성립
let user = {
  name: 'Seongil',
  gender: 'male'
};

const changeName = (user, newName) => {
  let newUser = user;
  newUser.name = newName;
  return newUser;
}

const user2 = changeName(user, 'modolee');

if (user !== user2) {
  console.log('유저 정보가 변경되었습니다.');
}

console.log(user.name, user2.name); // modolee modolee
console.log(user === user2); // true

우리가 원하던것과 전혀 다르게 동작한다.
이유는 object type의 특성상 주소값을 복사하게 되서, user2도 기존의 user의 name property를
가리키게 되므로, user의 네임까지 변경시켜버린다.

let user = {
  name: 'Seongil',
  gender: 'male'
};

const changeName = (user, newName) => {
  return {
    name: newName,
    gender: user.gender
  };
}

const user2 = changeName(user, 'modolee');

if (user !== user2) {
  console.log('유저 정보가 변경되었습니다.'); // 유저 정보가 변경되었습니다.
}

console.log(user.name, user2.name); // Seongil modolee
console.log(user === user2); // false

위 코드처럼 deep copy를 통해 immunitable을 보장 할 수있다.


6. undefined 와 null

  • 자바스크립트에서 없음 을 나타내는 값이 두개가있다
  • undefined와 null 이다

6-1) underfined

  • undefined는 사용자가 지정할 수 도있지만, JS엔진이 자동부여 할 때 도있다.

  • 엔진이 자동으로 부여하는 경우는 다음과 같다

    1. 값을 대입하지 않은 변수, 즉 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근

    2. 객체 내부의 존재하지 않는 프로퍼티에 접근하려할때

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

      var a;
      console.log(a); //(1) undefined 값을 대입하지 않은 변수에 접근
      
      var obj = { a:1 };
      console.log(obj.b); // (2) 존재하지 않는 props 에 접근
      
      var func = function() {};
      var c = func();
      console.log(c); //(3) 명시적인 반환값이 없는 함수에 반환값
  • 주의 할점은 '비어있는 요소' 와 'undefined를 할당한 요소'는 출력결과가 다른걸 유의 해야한다.

var arr1 = [undefined, 1];
var arr2 = [];
arr[2] = 1;

arr1.forEach(function (v,i) {console.log(v,i)}); // undefined 0 / 1 1
arr2.forEach(function (v,i) {console.log(v,i)}); // 1 1

// 엔진에 의해 할당된 undefined 같은경우, 아예 없는 값으로 취급이된다. 
// 메서드의 순환 대상에서 제외 된다는 것이다.
  • 값이 지정되지 않은 인덱스는 '아직은 존재하지 않는 프로퍼티'에 지나지 않는다.
  • 사용자가 지정한 undefined는 그 자체로의 값이다. (순회시 하나의 값으로 취급)
  • 가장 중요한것은 undefined를 직접 할당하지 않도록 주의해야한다.
  • 비어있음을 명시적으로 표현하고싶다면 null을 삽입하도록 하자.
  • 이렇다면 undefined는 오직 '값을 대입하지 않은 변수에 접근하고자 할때 자바스크립트 엔진이 반환해주는 값' 으로만 존재할것이다

0개의 댓글