javascript

[javascript] 자바스크립트의 값 / truthy,falsy

sewonzzang123 2022. 1. 6.
반응형

자바스크립트에서 값은 이상합니다.

타입을 가지고 있지 않지만 필요에 따라 타입이 변환되기도 하고, [] == 0 이 true 이고, 심지어 if([]) console.log('aa'); 도 정상적으로 동작합니다.

도대체 자바스크립트의 값은 어떻게 동작하기에 이렇게 될 수 있을까요?

 
[] == 0 // true

if([]) {
  console.log('어, 이게 왜 되지?'); // 출력 O
}

if(0) {
  console.log('어, 이게 왜 안되지?'); // 출력 X
}

모든것은 연산자에 따른 형변환의 값이 truthy, falsy 구분에 의한 현상입니다.

 

값의 종류

자바스크립트에는 두 가지 종류의 값이 있습니다.

하나는 Primitive Value(원시 값) 이고, 다른 하나는 Reference Value(참조 값) 입니다.

원시값에는 number, String, boolean, null, undefined가 있고,

참조값에는 array, function, object 가 있습니다.

 

연산자에 따른 형변환 +

자바스크립트는 연산자에 따라 형변환이 다르게 일어납니다. 또, 값이 원시값이냐 참조값이냐에 따라서도 다른 형변환이 일어납니다.

 
1+'1' // '11'

위 예시는 number 와 String을 + 연산했을 떄의 결과입니다. '11'의 문자열이 나왔습니다.

이 결과는 값의 형변환에 의한 결과로 볼 수 있습니다. number 1이 String 1로 변환이 되고, 두 문자열을 합친 새로운 문자열을 반환한 것으로 볼 수 있습니다.

 

+ 연산자는 다른 수학 연산자와 다르게 덧셈 연산 외에 두 문자열을 합치는 특별한 연산을 가지고 있습니다.

그렇다면 왜 덧셈이 아닌 두 문자열을 합치는 연산을 선택한 것일까요?

Number('alphabetString'); // NaN
Number('123'); // 123

123.toString(); // '123'
1.23.toString(); // '1.23'

'hello ' + 'world' // 'hello world'
1 + 'hello' // '1hello'
'3' + 5 // '35'

모든 문자열이 숫자로 변환될 수 있는 것은 아니지만, 모든 숫자는 문자열로 변환될 수 있기 때문입니다.

따라서 + 연산에 문자열과 숫자가 연산될 경우, 숫자를 문자열로 변환 후에 연산을 하는 것입니다.

 

 
1 + true // 2
2 + false // 0

boolean은 오직 두 가지 값을 가지고 있습니다. 다양한 종류의 문자열과는 다르게 단 두가지의 값을 가지고 있기 때문에 수샂로 형변환이 용이합니다.

true 는 1, false 는 0으로 변환하면 아주 간단합니다.

따라서 숫자와 boolean을 + 연산을 할 때는 boolean을 숫자로 변환 후에 연산을 합니다.

 

그렇다면, +를 제외한 다른 수학 연산자에 대해서는 어떨까요?

 
4 - '1' // 3
1 * '2' // 2
2 / '1' // 2

'hello' - 'ello' // NaN

-, *, / 연산자는 오직 수학적 연산을 가지고 있습니다. 즉 피연산자로 숫자만 올 수 있는 것이죠.

따라서 연산에 사용 되는 모든 값은 숫자로 변환 후에 연산을 하게 됩니다.

위 연산자 뿐만 아니라 다른 수학적 연산자 모두 동일하게 동작합니다.

이 때, 숫자로 변환될 수 없는 값은 NaN 값을 가집니다.

 

참조값의 형변환

 

자바스크립트에서의 각 연산자는 원시값을 피연산자로 가지고 있어야 합니다.

즉, 참조값은 연산에 사용할 수 없습니다.

 

[] + 1 // '1'
[] == 0 // true

하지만 array는 참조값인데 위의 연산이 가능한 것일까요?

그것은 바로 참조값이 자바스크립트 엔진에 의해 자동으로 원시값으로 형변환이 되었기 때문입니다.

위 예시를 보면 array 는 String으로 변환이 되는 것을 알 수 있습니다.

 

array 는 toString() 함수를 가지는데, 이 함수는 각 원소를 , 로 구분하여 문자열로 만드는 함수입니다.

따라서 array가 연산에 사용됐을 때 내부적으로 toString() 함수가 호출되어 array를 String으로 바꾸고 연산을 하게 됩니다.

[] + 1 => [].toString() + 1 => '' + 1 => '1'

 

그렇다면 Object는 어떨까요?

Object도 참조값이지만 array와 마찬가지로 연산에 사용되면 자동으로 원시값으로 형변환이 되어 연산됩니다.

 
const obj = {};
obj + 1; // '[object Object]1'

{} + 1; // '{}' 가 block으로 취급

놀랍게도 Object도 toString() 함수가 존재하고, 그 결과값은 [object Object]입니다.

array와 동일하게 아래와 같은 과정을 거쳐 연산을 하게 됩니다.

 
obj + 1 => obj.toString() + 1 => '[object Object]' + 1 => '[object Object]1'

==연산에서의 형변환

 

다른 타입을 가진 두 값이 같은지 비교하기 위해서는 당연히 형변환이 선행으로 이루어져야 합니다.

각 피연산자가 == 연산에서 각각 어떻게 형변환이 되는지 알아봅시다. (=== 연산자는 형변환이 발생하지 않습니다.)

 

 
if(1 == '1') {
  console.log('Hello World!'); // 출력 O
}

if(1 == '') {
  console.log('Hello World!'); // 출력 X
}

if(0 == '') {
  console.log('Hello World!'); // 출력 O
}

Number(''); // 0
0.toString(); // '0'

간단한 예시로 문자열과 숫자를 비교했을 때, 문자열이 숫자로 변환됨을 알 수 있습니다.

만약, 숫자가 문자열로 변환이 되는 것이라면 세 번째 if문이 동작하지 않아야지만 동작하기 때문에 숫자가 문자열로 변환되는 것이 아님을 알 수 있습니다.

 

참조값이 == 연산에 사용되는 경우에는, 위에서 설명한 것과 마찬가지로 참조값이 우선 toString() 연산을 통해 원시값으로 형변환됩니다. 그리고 마찬가지로 동일한 연산을 수행하게 됩니다.

 

Truthy와 Falsy


Truthy 와 Falsy는 자바스크립트에서 boolean을 기대하는 구문에서 각 값이 true와 false 중 어떤 값을 가지냐를 나타내는 값입니다.

즉, if, while 등의 구문에서 사용되는 값이 true나 false를 나타내는 것입니다.

 

먼저, Falsy한 값은 0, -0, 0n(bigint), '', null, undefined, NaN이 있습니다.

Truthy한 값은 Falsy한 값을 제외한 모든 값입니다.

 
0 // falsy => false
'' // falsy => false
123 // truthu => true
'Hello World' // truthy => true
[] // truthy => true - string으로 변환되지 않음
[1, 2, 3] // truthy => true - string으로 변환되지 않음

여기서 주의해야 할 점은, truthy와 falsy를 결정하는 과정에서는 형변환이 발생하지 않습니다.

즉, array가 String으로 변환되지 않습니다.

 

 
if([]) {
  console.log('어, 이게 왜 되지?'); // [] = truthy, 출력 O
}

if(0) {
  console.log('어, 이게 왜 안되지?'); // 0 = falsy, 출력 X
}

 

요약

  • 문자열과 숫자의 + 연산은 숫자가 문자열로 형변환된다.
  • 문자열과 숫자의 + 연산을 제외한 모든 수학 연산에서 문자열이 숫자로 형변환된다.
  • 문자열과 숫자의 == 연산은 문자열이 숫자로 형변환된다.
  • 참조값은 연산을 위해 원시값으로 변환되어야 하며 그 값은 toString() 결과이다.
  • 따라서 [] == 0 의 값은 '' == 0 , 0 == 0 과정에 따라 true를 반환한다.

 

 

참고https://velog.io/@cada/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%EC%84%9C-0%EC%9D%B4-true%EC%9D%B8-%EC%9D%B4%EC%9C%A0

 

자바스크립트에서 ([] == 0)이 true인 이유

본 글은 아래에서 참고하여 작성되었습니다. 내용에 대해 더 자세하게 알고싶으신 분은 아래의 링크를 참고해주세요.Academind - Avoiding Javascript Type Conversion IssuesJavascript MDN - Truthy/Falsy자바스크립

velog.io

 

반응형

댓글