자바스크립트 딥다이브 - 타입변환

ChoiYongHyeun·2023년 12월 7일
0

타입변환

모든 값은 데이터 타입 을 갖는데 개발자의 의도에 따라 다른 타입으로 변환 할 수 있다.

var x = 10;

var s = x.toString();

console.log(x, typeof x); // 10 number
console.log(s, typeof s); // 10 string

number 인 식별자 xstring 형태로 타입을 변환하여 s 식별자에 할당 했을 때

타입을 변환하여 할당 할 수 있다.

이를 명시적 타입 변환 또는 타입 캐스팅이라고 한다.

개발자의 의도와 상관 없이 타입이 변환되는 경우는 암묵적 타입 변환 이라고 한다.

var x = 10;

var s = x + '1';

console.log(s, typeof s); // 101 string

암묵적 타입 변환

자바스크립틍 엔진은 표현식을 평가 할 때 개발자의 의도와 상관 없이 코드의 문맥을 고려해 암묵적으로 데이터 타입을 변환 할 때가 있다.

console.log(5 + '10'); //510
console.log(5 * '10'); // 50
console.log(5 + '10');
console.log(!0); // true
if (1) {
  console.log('True입니다');
} else {
  console.log('False입니다');
} // True입니다.

암묵적 타입 변환은 연산되는 피연산자의 문맥에 따라 결정된다.

예를 들어 피연산자가 모두 문자열이여야 가능한 5 + '10' 같은 경우는 number5 를 문자열로 타입을 변환하고

피연산자가 모두 숫자열이여야 가능한 5 * '10'string10 을 숫자열로 타입을 변환한다.

불리언이 적합한 경우엔 불리언 타입으로 변환한다.

진짜 개열받는다

명시적 타입 변환

개발자의 의도에 따라 명시적으로 타입을 변경하는 방법은 다양하다.

표준 빌트인 생성자 함수 (String , Number , Boolean)를 new 연산자 없이 호출하는 방법과 빌트인 메소드를 사요하는 방법, 암묵적 타입 변환을 이용하는 방법이 있다.

빌트인 메소드

자바스크립트의 new 연산자는 객체 인스턴스를 생성하는 데 사용되는 특별한 연산자입니다. new 연산자는 주로 생성자 함수와 함께 사용되며, 생성자 함수를 호출하여 새로운 객체를 만듭니다. 이 객체는 해당 생성자 함수의 인스턴스가 되며, 생성자 함수에서 정의한 프로퍼티와 메서드를 상속합니다.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 생성자 함수를 사용하여 객체 인스턴스 생성
var person1 = new Person('John', 30);
var person2 = new Person('Jane', 25);

console.log(person1); // Person { name: 'John', age: 30 }
console.log(person2); // Person { name: 'Jane', age: 25 }

문자열 타입으로 변환

  1. String 생성자 함수를 new 연산자 없이 호출하기
console.log(String(1)); // '1'
  1. Object.prototype.toString 메소드를 사용하는 방법
console.log((1).toString()); // '1'
  1. 문자열 연결 연산자를 이용하는 방법
console.log(1 + '');

숫자 타입으로 변환

  1. Number 생성자 함수를 new 연산자 없이 호출하는 방법
console.log(Number('1')); // 1
  1. parseInt, parseFloat 함수를 사용하는 방법

parseInt

console.log(parseInt('1')); // 1
console.log(parseInt('1.2')); // 1

이 방법은 문자열만 변환 가능하며 정수로 변환한다.

parseFloat

console.log(parseInt('1.2')); // 1
console.log(parseFloat('1.2')); // 1.2

이 방법은 실수형으로 변환한다.

  1. + , * 연산자를 이용하기
console.log(+'1'); // 1
console.log('1' * 1); // 1

불리언 타입으로 변환

  1. Boolean 생성자 함수를 new연산자 없이 사용
console.log(Boolean(0)); // false
console.log(Boolean('1')); //true
  1. ! 부정 논리 연산자를 두 번 사용하는 방법
console.log(!!'1'); // true
console.log(!!0); // false
console.log(!!''); // false
console.log(!!'dog'); // ture

단축 평가

논리 연산자를 사용한 단축 평가

이전에 논리합 (||) 또는 논리곱 (&&) 연산자 표현식의 평가 결과는 불리언 값이 아닐 수 있다고 했다.

두 연산자 표현식은 언제나 2개의 피연산자 중 어느 한쪽으로 평가된다.

console.log('cat' && 'dog'); // dog
console.log('cat' || 'dog'); // cat

논리 연산 당하는 피연산자는 boolean 값이여야 하기 때문에 두 문자열은 boolean 값으로 암묵적 타입 변환이 된다.

&& 논리곱 연산자는 두 피연산자 모두 true 여야 true 를 반환한다.

좀 더 엄밀히 말하면 연산자들을 순차적으로 true 인지 확인하며 모두 true 일 경우 가장 마지막 피연산자의 값을 반환한다.

만일 피연산자 값이 타입 변환 없이 true 였다면 true 값을 반환한다.

해당 사항에서 dog 는 타입이 string 이지만 비교를 위해 암묵적 타입 변환 되어 true 로 평가된다.

하지만 dog 가 암묵적 타입 변환이 되어 평가되었다고 하더라도 dog 자체의 값은 dog 로 남아있기 때문에 dog 가 반환된다.

|| 논리합 연산자는 피연산자 중 하나라도 true 라면 true 가 나온 피연산자 값을 반환한다.

그렇기에 cat 에서 이미 true 로 평가되어 cat 이 반환된다.

이처럼 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환하는 것을 단축 평가 라고 한다.

단축 평가는 표현식을 평가하는 중 평가 결과가 확정된 경우 나머지 평과 과정을 생략한다.

단축 평가를 사용하면 if 문을 대체 할 수 있다.

var done = true;
var message;

if (done) message = '완료';
console.log(message);

만약 어떤 액션이 취해져 donetrue라면 메시지의 값을 완료 라고 정하고 싶은 경우

조건문을 이용하면 다음처럼 된다.

var done = true;

message = done && '완료';
console.log(message);

단축 평가를 이용하여 message 값에 done 이 트루라면 완료 값을 넣을 수 있다.

어차피 할당되는건 마지막 피연산자인 완료 문구이니까 말이다.

만약 반대로 donefalse 라면 하고 미완료 란 문구를 넣고 싶다면

var done = false;

message = done || '미완료';
console.log(message);

다음처럼도 할 수 있다.

어차피 논리합 연산자에서 donefalse 더라도 미완료 문구 자체는 true 이기 때문에 미완료 라는 메시지가 할당된다.

var done = true;

if (done) {
  message = '완료';
} else {
  message = '미완료';
}

console.log(message);

그럼 다음과 같은 if else 문을 논리합, 논리곱 연산으로 간단하게 하려면 어떻게 될까 ?

var done = true;
message = done ? '완료' : '미완료';
console.log(message);

굿

단축 평가가 유용하게 쓰이는 경우

객체를 가리키기 위해 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조 할 때

객체는 키와 값으로 구성된 프로퍼티의 집합이다.

객체를 가리키기를 기대하는 변수의 값이 객체가 아니라 null 또는 undefined 인 경우 객체의 프로퍼티를 참조하면 타입 에러가 발생한다.

elemvalue 값을 참조하려 했으나 elem 자체가 null 값이라 참조가 되지 않는 경우

var elem = null;
var value = elem.value; // TypeError: Cannot read properties of null (reading 'value')

단축 평가를 이용해 elem 의 값이 null 값이면 elem 값을 반환, null 값이 아니면 elemvalue 값을 반환.

var elem = null;
var value = elem && elem.value;
console.log(value); // null

elem 의 경우가 null 일 때에는 false 로 평가되어 단축 평가로 인해 중단되고 elem 값을 반환한다.

반대로 elem 의 경우가 null 이 아닐 경우에는 두 번째 값인 elem.value 또한 false 가 아니기 때문에 두 번째 피연산자인 elem.value 값을 반환한다.

함수의 매개변수에 기본값을 설정 할 때

함수를 호출 할 때 매개변수를 전달하지 않으면 매개 변수에는 undefined 가 할당된다.

단축평가를 이용해 undefined 로 인해 발생 할 수 있는 에러를 방지 가능하다.

function getStringLength(str) {
  str = str || '';
  return str.length;
}

console.log(getStringLength());

매개변수로 들어온 str 값이 존재하지 않는다면 '' 값이 str 에 매겨져 길이가 0으로 맵핑된다.

단축평가를 이용 할 수도 있고

function getStringLength(str = '') {
  return str.length;
}

기본 매개 변수에 '' 값을 넣어둘 수도 있다.

옵셔널 체이닝 연산자

단축 평가를 이용해 elem 의 값이 null 값이면 elem 값을 반환, null 값이 아니면 elemvalue 값을 반환.

var elem = null;
var value = elem && elem.value;
console.log(value); // null

위에서 단축 평가를 이용해 elem 값이 null 이나 undefined 인지 확인 했다면 ES11
에서 도입된 옵셔널 체이닝 연산자를 이용해 사용 할 수 있다.

var elem = null;
var value = elem?.value;
console.log(value); // undefined

그럼 논리곱 연산자를 쓰면 되는데 왜 옵셔널 체이닝 연산자를 도입했을까 ?

논리곱 연산자의 한계점

예시를 들어 이해해보자

function getStringLength(str) {
 return str && str.length;
}

console.log(getStringLength('')); // ''

다음처럼 논리곱 연산자를 이용해서 들어오는 str 값이 null 값이 아닐 경우 문자열의 길이를 구해달라고 하는 함수 getStringLength 가 있다.

이 때 str 값으로 '' 가 들어왔다면 (빈 문자열)

빈 문자열의 길이인 0return 하길 원하지만 ''return 된다.

그 이유는 '' 빈 문자열은 암묵적 타입 변환에 의해 false 로 취급 되기 때문에 strreturn 되는 것이다.

암묵적 타입 변환으로 인해 ''null 모두 false 로 취급 받는 것이지

''null 값이 아니다.

function getStringLength(str) {
  return str?.length;
}

console.log(getStringLength('')); // 0

하지만 옵셔널 체이닝 연산자를 사용하면 엄격하게 strnull , undefined 가 아니라면 길이를 구하려 할 것이다.

옵셔널 체이닝은 엄격하게 null , undefined 가 아니기만 하면 다음 코드를 실행한다.

null 병합 연산자

옵셔널 체이닝 연산자는 좌항이 null 일 경우 좌항의 값을 return 하고 좌항이 null 이 아닐 경우엔 우항의 값을 return 했다.

null 병합 연산자는 좌항이 null 일 경우 우항의 값을 return 한다. 좌항이 null 이 아닐 경우엔 좌항의 값을 return 한다.

null 병합 연산자는 변수에 기본값을 설정 할 때 유용하다.

function createUserName(name) {
  return name || 'default name';
}

console.log(createUserName()); // default name 
console.log(createUserName(0)); // default name
console.log(createUserName('')); // default name

만약 유저 네임을 만들 때 유저가 이름을 입력하지 않을 경우 우리가 설정한 defaulte name 으로 지정하고 싶다고 해보자

그렇게 하기 위해 논리합 연산자를 사용했다.

좌항에 들어가는 namefalsy 값이라면 우항의 값이 return 되도록 말이다.

그런데 만약 유저가 ''0 을 이름으로 지정하고 싶더라도 falsy 한 값으로 인식되어 defaulte name 으로 설정된다.

그러니 이 또한 namenull 값이거나 undefined 인지를 엄격하게 확인해야 한다.

?? 이용하기

function createUserName(name) {
  return name ?? 'default name';
}

console.log(createUserName()); // default name
console.log(createUserName('')); // ''
console.log(createUserName(0)); // 0

null 병합 연산자를 이용하면 엄격하게 null 이거나 undefined 인 값에 대해서만 default name 을 할당 시킬 수 있다.

profile
빨리 가는 유일한 방법은 제대로 가는 것이다

0개의 댓글