JS 값

gang_shik·2025년 3월 15일
0

JavaScript

목록 보기
3/23

타입 시스템

  • JS는 굉장히 느슨한 동적 타입의 언어임
  • 프로그램 처리 과정이 런타임 시점에서 자동으로 파악되기 떄문에 그럴 때 보는 타입에서만 보임
  • 그래서 타입을 할 때 굉장히 조심해서 다뤄야함
  • 타입은 보통 원시값(Primitive)과 객체타입(Reference) 2가지로 나뉘어짐
  • 참고자료

원시값

typeof undefined // 'undefined'
typeof true // 'boolean'
typeof 'string' // 'string'
typeof 123 // 'number'
typeof 9007199254740992n; // 'binint' Number.MAX_SAFE_INTEGER를 넘는 값
typeof Symbol() // 'symbol'
typeof null // 'object'
  • 위의 타입을 대표적인 원시값 타입이라고 볼 수 있음
  • 원시 타입은 또한 불변하다는 특징을 가지고 있음
  • 아무리 문자열을 toUpperCase로 주더라도 값 자체가 바뀌지 않음(boolean도 마찬가지), 아래와 같이 재할당을 해야함(불변한 값이므로)
let test = 'string';
test = test.toUpperCase();

console.log(test);

const bool = false;
bool = !bool;

console.log(bool);
  • 그러지 않으면 그 기본값은 변하지 않음

참조 타입

  • 객체 타입, 참조 타입, Reference 타입이라고 부름
  • 객체, 배열, 함수를 참조 타입이라고 할 수 있음
const object = {};
const array = [];
function func() {}
  • 실제 메모리에 존재하는 참조 타입일 경우 instanceof함수로 확인해볼 수 있음
  • 객체의 경우 아래와 같이 객체 안에 속성이 들어가고 (, 연산자를 통해서 다양한 값을 넣을 수 있음(함수도 넣을 수 있고 다른 객체 다양하게 들어갈 수 있음)
  • 그래서 이를 데이터 컬렉션이라고도 하는 경우가 있음
  • array 같은 경우도 함수도, 배열도 다양하게 넣을 수 있음
  • 이러한 것의 특징은 불변하지 않고 가변적이면서도 그 안의 값은 예시처럼 메모리 주소가 가지고 있음
  • 그래서 Object 타입의 경우 일종의 메모리를 가지고 주소를 가지고 있는 것(어딘가에 값이 저장되고)
const object = {
  name: 'jang', // @0001 <- 'jang'
  age: 11,
  arr: [],
  func: function() {},
  child: {}
};

const array = [[], 11, 'jang', function() {}];
  • 객체의 경우, 아래와 같은 성격으로 가변적이라고 볼 수 있음
const obj = {
  str: 'string'
}
// 단일 연산자로 접근 가능(하지만 값이 바뀌진 않음)
obj.str.toUpperCase();

// 아래의 특징으로 인해 가변적인 것, 위의 객체에서 없는 속성으로 `.` 사용으로 객체에 추가됨(그래서 가변적)
obj.num = 123
obj.bool = true
  • 배열의 경우도 아래와 같이 볼 수 있음(마찬가지로 불변적이면서 가변적이라는 것)
const arr = [1,2,3];
console.log(arr[0]);
// 없는데 추가됨(그래서 가변적)
arr[3] = 1000

undefined & null

  • 변수는 선언 & 할당 & 선언과 동시에 할당되는 케이스로 구분할 수 있음
  • 이 때 undefined의 경우 할당되지 않은 경우임(정의가 되지 않은 것), 즉, 변수를 선언만 하고 할당 & 정의를 하지 않은 것
  • null의 경우 직접 null을 지정한 것임, 그래서 이 차이가 undefined와 null의 차이임
let variable; // 선언
const initValue = null // null을 지정

variable // undefined
initValue // null
  • 비어있는 값을 처리하기 위해서 임의로 null, undefined를 넣어서 쓰는 경우도 있음
  • 이 때 undefined, null 모두 !를 쓰면 true가 되고, !!로 하면 false가 됨(둘 다 같은 값으로 여겨짐, 느슨한 비교일 경우)
  • 하지만 이를 명시적으로 Number(undefined)로 하면 NaN으로 되고 Number(null)로 하면 0이 됨
  • 이는 느슨한 비교와 명시적으로 한 경우, 다 다름
  • 그래서 어느정도 규칙을 정해야 규칙과 목적성 있게 해당 값을 다룰 수 있음(둘 중 하나만 명확하게 기준을 잡고 쓰기)

래퍼 객체

  • 원시값의 래퍼 객체라고 아래와 같이 존재함(파스칼 케이스로 정의해서 씀, 생성자 함수로 만듬)
  • 이렇게 생성자 함수 래퍼 객체로 만든 것은 타입이 다름(object임), 그러한 객체로 인스턴스가 생성됐다고 볼 수 있음
const bool = false;
const num = 123;
const str = 'string';

const bool2 = new Boolean(false);
const num2 = new Number(123);
const str2 = new String('string');

// 아래의 경우 false임, 래퍼 객체와 주소가 다르기에
console.log('string' instanceof String);
  • 이를 원시값으로 되돌리고자 한다면 valueOf()를 쓸 수 있음
  • 래퍼 객체를 안 쓰는게 나을 수 있음
  • string을 원시값으로 쓸 때, 래퍼객체로 만들고 가비지 콜렉터로 사라짐, 다른 객체로써 불러올 때도 마찬가지
  • 래퍼객체 안에 아주 많은 메소드들이 있는데 그래도 그냥 리터럴로 편하게 써도 무방함

타입 변환

  • !!로 Boolean으로 형변환을 하거나 명시적으로 Number(값), String(값), Boolean(값), Array.from() 등 있음
  • 아래와 같이 암시적인 형변환도 있음.
// 문자열로 형변환됨(숫자 + 문자열)
const result1 = 1 + '입니다'

// 문자열로 변환됨 아래 값은 1111로 바뀜
const result2 = '11' + 11

// number로 형변환 됨
const result3 = '2' * '2'
const result4 = '5' * 3

// 문자열로 형변환됨
const result5 = ['111'] + '111'
  • 위와 같은 경우 명시적으로 형변환해서 하는게 좋음, js의 경우 형 변환이 문자열로 되는 경우도 꽤 있음(불명확함)
const result1 = String(1) + '입니다'

const result2 = Number('11') + 11

const result3 = Number('2') * Number('2')
const result4 = Number('5') * 3

// 문자열로 형변환됨
const result5 = Number(String(['111'])) + 111
  • 그래서 명시적으로 형변환을 하고 확실히 해야함. 사용자의 입력을 받고 처리하기 때문에 필히 명시적으로 해야함
profile
측정할 수 없으면 관리할 수 없고, 관리할 수 없으면 개선시킬 수도 없다

0개의 댓글