loading
반응형

자바스크립트(javascript) - 타입(유형), 형, 변환 개념잡기

 

순번 링크페이지 아래 제목을 클릭하면 해당 링크페이지로 이동 됩니다.
1 JS - 형 변환에 대하여 - (1)
2 JS - 형 변환에 대하여 - (2)
3 JS - 형 변환에 대하여 - (3)
4 JS - 형 변환에 대하여 - (4)
5 JS - 형 변환에 대하여 - (5)
6 JS - 형 변환에 대하여 - (6)

 

▶ Number 형 변환

 💻 부울 값 true & false  

부울 값 true와 false를 Number로 형 변환을 하면?

var a = true;
var b = false;

console.log(Number(a)); // 1
console.log(Number(b)); // 0


console.log(Number(undefined));// NaN
console.log(Number(null)); // 0

 

부울 값  trueNumber로 형 변환하면 1이 되고, 

부울 값 falseNumber로 형 변환하면 0이 된다.

 

이해가 안 되는 건 nullNumber() 형 변환을 하면 0이 된다는 건데... undefinedNumber() 형 변환하면

NaN이 된다는 거다... 이유는 잘 모르겠다.. 

 

그냥 자바스크립트가 그리 해석을 하니 그리 알고 있어야겠다.

암튼 부울 값을 number로 형 변환했을 시에 true는 1이고, false는 0이 된다는 사실만 알자.

 

그렇다고 이게 참/거짓으로 판단하지 말자.

이 말은 true가 참이니깐 형 변환하면 1이고 당연히 이 숫자 1은 참이 아니겠느냐? 

 

또는 false가 거짓이니깐 형 변환하면 0이고 당연히 이 숫자 0은 거짓이 아니겠느냐?

이렇게 일반적인 생각을 할 수 있는데,

자바스크립트에선 이런 생각을 하면 안 된다. 

 

1이 거짓이 될 수도 있고, 0이 참이 될 수도 있다.

이 말인즉슨,

 

내가 거짓이라고 생각했는데 거짓이 아니었다는 것과참이라고 생각했는데 이게 거짓이었다는 결과가 있기 때문에 자바스크립트에서는

 

너무 단정 짓게 생각하면 안 된다.왜 그런지 Boolean 형 변환의 밑에 글에서 설명하겠다.

 

 

 💻 객체 & 배열  

객체(object)와 배열(Array)Number로 형 변환하면?

여기서 객체랑 배열도 Number로 형 변환이 가능하나? 라고 생각할 수 있는데 가능하다.

 

객체나 배열은 단일 값이 아니기 때문에 객체나 배열은 형 변환이 일어나면 

  1. valueOf() 메서드를 제일 먼저 찾고, 있다면 이 함수를 실행시켜 강제로 형 변환을 한다.
  2. valueOf()가 없다면 toString() 메서드를 찾고 이 함수를 실행시켜 강제로 형 변환을 한다.

 

어리둥절할 것이다.

배열이나 객체가 형 변환이 되는 것부터 시작해서 valueOf 메서드라느니 toString 이라느니 말이다...

이제 이 부분을 확인해보자.

 

※ 자바스크립트에서는 배열도 객체이다

객체나 배열에서 형 변환이 일어나는 순간 객체는 valueOf() 메서드를 찾는다고 했다. 

이것은 ECMAScript5 사양(spec)을 보면 나와있다. section 9.1을 보면

 

ECMAScript5 사양(spec) section 9.1

위 링크로 들어가면 확인이 가능하다.

 

ECMAScript5 spec #9.1

 

보면 객체는 기본 값으로 변환하기 위해 어떠한? 작업을 하는데

그 작업이 9.1 ToPrimitive 라는 추상작업을 진행을 하는데

 

그 내용을 살펴보면 위 빨간 박스 쳐 놓은 부분을 확인해보면 DefaultValue 작업을 한다고 한다.

그럼 이 DefaultValue 작업이 무엇인지 확인을 해봐야 하는데

 

ECMAScript5 사양(spec) section 8.12.8

위 링크로 들어가면 확인이 가능하다.

 

ECMAScript5 spec #8.12.8

 

이 내용을 확인해보면 이 [[DefaultValue]] 에서 하는 행동들이 나와있다.

즉, valueOf() 메서드가 있는지 확인을 먼저 하고 있으면 실행을 한다는 것이다.

 

없다면 toSTring() 메서드를 확인하고 실행을 한다는 것이다.

만약 두 작업 모두 기본 값을 제공할 수 없는 상태라면 TypeError가 발생된다.

 

자 이제 예로 확인해보자.

 

// 첫번 째 예제
var obj_A = {
    a:'100'
}

var obj_B = {
    a:'100',
    valueOf:function(){
    	return this.a;
    }
}

console.log(Number(obj_A)); // NaN
console.log(Number(obj_B)); // 100

 

 

obj_A를 Number(obj_A) 형 변환해서 console.log로 출력을 해보면 NaN 이 찍힌다.

즉, valueOf 메서드가 없기 때문에 그렇다.

 

obj_B를 Number(obj_B) 형 변환해보면 숫자 100이 찍힌다.

obj_B의 프로퍼티 a의 값 문자열 '100' 이 숫자 100으로 형 변환이 되어서 출력이 되었다.

 

이번엔 toString 메서드도 되는지 확인해보자.

// 첫번 째 예제
var obj_A = {
    a:'100'
}

var obj_B = {
    a:'100',
    toString:function(){
    	return this.a;
    }
}

console.log(Number(obj_A)); // NaN
console.log(Number(obj_B)); // 100

 

위 예제와 똑같고, valueOf를 단지 toString으로 바꿨다.

실행해보면 위 결과와 똑같이 나온다. 

 

즉, 객체를 형 변환 시도를 하려고 하면 객체는 추상작업인 ToPrimitive라는 작업을 하는데

이 중 객체에 대한 행위 [[DefaultValue]] 이것을 시도하는데

 

이것이 ECMAScript5 spec 8.12.8에 나와있는 데로 valueOf, toString 메서드를 찾고 실행한다는 것이다.

이번엔 배열로 확인해보자.

 

var arr = [1,2,'4'];

arr.toString = function(){
	return this.join('');
}

console.log(Number(arr)); // 124

 

이 코드처럼 arr에 대한 number의 형 변환을 시도하려고 하면 toString을 먼저 실행하고,

값을 얻은 후에 형 변환이 일어난다. 그래서 결과 값은 124.

 

 

 

반응형

 

 

▶ Boolean 형 변환

 💻 참 / 거짓  & 1과 0  

아까 말한 참과 거짓/ 1과 0은 동일하다 라는 다른 언어에서는 맞는 말일 수도 있지만, 자바스크립트에서는 아니다. 

 

자바스크립트에서는 숫자 1/0은 그냥 숫자일 뿐이고,true/false 는 그냥 부울 값이다.

 

이 부분을 알아보기 전에 Boolean 형 변환이 일어날 때,

어떤 현상이 일어나는지 확인해보고 그다음에 알아보자.

 

Boolean 형 변환의 일어날 때 자바스크립트는 아래 링크에 나온 내용을 실행한다.

ECMAScript5 사양(spec) 9.2 ToBoolean

위 링크에서 확인이 가능하다.

 

ECMAScript5 spec #9.2

 

Boolean 형 변환이 일어나면 위 링크에서 9.2 ToBoolean에 나온 행동을 시도하는데,

Boolean() 실행하면 거짓으로 판별하는 값은

  • undefined
  • null
  • false
  • +0, -0, and NaN
  • ""

이렇다 이렇게 강제적으로 형 변환을 시도하면 위 나열한 값에 대해선 false로 변환이 된다.

진짜로 되는지 실행해보자.

console.log(Boolean(undefined)); // false
console.log(Boolean(null)); // false
console.log(Boolean(false)); // false
console.log(Boolean(+0)); // false
console.log(Boolean(-0)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean("")); // false

 

console.log 결과화면

 

보이는가? 전부 false 가 나왔다.

위 값에 대해선 Boolean으로 형 변환을 시도하면 전부 거짓의 값을 얻을 수 있다.

즉, 이 거짓의 목록 리스트에 대해선 Boolean으로 형 변환을 시도하면 거짓의 값을 확인이 가능하다는 거다.

 

이제 혼란스러운 부분을 봐보자.

아까 전에 말한 참과 거짓/ 1과 0은 동일시하지 말라는 부분을 알아보자.

var bool = new Boolean(false);
var num = new Number(0);
var string = new String('');


console.log(Boolean(bool)); // ???
console.log(Boolean(num)); //???
console.log(Boolean(string)); // ???

 

이 결과 값들은 어떻게 나올까?

아마 머리가 띵 할 것이다. 전부 true로 나온다.

 

Boolean 형 변환을 시도했는데 우리가 알고 있는 일반적인 상식? 선에서 알고 있는 것과 다르게 나왔다.

이제 그 이유를 설명해보자.

 

bool 변수는 Boolean(bool) 형 변환했을 때 왜 true 가 나오는가?

console.log(bool); // true

이렇게 확인을 해봐도 true 가 나올 것이다. 당연히 값이 true인데 형 변환을 해도 true이지 않겠는가?

그런데 이게 궁금하지 않을 것이다.

 

 var bool = new Boolean(false);  이렇게 선언했는데 왜 true 가 나오냐는 거인데....

다른 글에도 new 생성자로 네이티브 함수를 실행하지 말라라는 글에도 쓴 적이 있긴 한데

 

이렇게 선언이 되었을 경우에 bool 변수는 Boolean 타입의 객체가 되어버린다.

즉, bool 변수는 그냥 객체이다.

 

 

Boolean 타입을 가진 객체

bool 변수

보이는가? 

다시 설명하자면 bool 변수는 Boolean 타입의 객체인데,

즉, Boolean 타입의 객체 bool 은 원시적 데이터[[PrimitiveValue]]  false의 값을 가진 객체이다.

 

라고 설명하면 이해가 될 것이다.

그래서 console.log(bool); 을 출력해보면 true 가 나오는 것이다.

근데 왜? true 일까?

 

즉, bool 객체는 자바스크립트가 인지할 땐 실제로 존재하는 객체이기 때문에 참으로 판단을 한 것이다.

그래서 bool 이란 객체에 원시적 데이터는 false라는 값을 가지고 있을지 몰라도 bool 객체는 존재하는 

참이 되는 것이다. 

 

Number 도 마찬가지다. 저기 num 변수는 console.log(num) 찍어도 0이 나오는데...

사실 이놈도 new로 생성했기 때문에 객체이다.

 

당연 string 변수도 마찬가지다. new 생성자로 생성했기 때문에...

자, 위에서 아까 거짓으로 나오는 값들을 잘 봐보자

 

var bool = false;
var objBool = new Boolean(false);

console.log(Boolean(bool)); // false
console.log(Boolean(objBool)); // true


var num = 0;
var objNum = new Number(0);

console.log(Boolean(num)); // false
console.log(Boolean(objNum)); // true


var string = '';
var objString = new String('');

console.log(Boolean(string)); // false
console.log(Boolean(objString)); // true

 

 

이렇듯 우리가 이런 부분에서 확인을 할 수 있는 부분은, 실제 해당하는 변수가 명시적인

즉, 직접적으로 거짓의 값을 가직고 있느냐? 없느냐?로 판단해야 한다.

 

다시 말해, 위 코드에서도 확인할 수 있듯이 num과 objNum이라는 숫자를 console.log 찍어보면 0이지만, 

num은 원시 데이터 숫자 0을 담고 있고, objNum은 Number의 객체이며 원시 데이터 값은 0을 가지고 있다.

 

그러므로 자바스크립트는 두 개의 변수 num과 objNum을 형 변환했을 경우 참과 거짓을 판명할 때,

num은 아까 위에서 살펴보았듯이 0은 (+0, -0) 은 false로 보기 때문에 false(거짓)으로 판별하고

 

objNum은 객체이니까, objNum의 원시적인 값은 0 일지라도 objNum 자체가 실질적으로 존재(참)하는의 객체이기 때문에 참인 값이 나오는 것이다.

 

그래서 우린 잊지 말아야 할 부분이

해당 변수에 명시적으로 거짓의 값이 들어 있느냐 없느냐? 이걸 판별해야 한다. 

 

 

다시 말해

  • undefined
  • null
  • false
  • +0, -0, and NaN
  • ""

이러한 값이 존재하면 무조건 거짓이다.

하지만 이 외에 값은 잘 확인해보고 혼동되지 않게 확인해봐야 한다.

 

이제 다시 또 혼동되는 부분을 확인해보자.

var stringBool = 'false';
var stringNum = '0';
var stringSpace = "''";


console.log(Boolean(stringBool)); // ???
console.log(Boolean(stringNum)); // ???
console.log(Boolean(stringSpace)); // ???

 

 

이렇게 전부 Boolean으로 형 변환이 일어났을 경우,

결과가 어떻게 나올까? false라고 생각했다면 혼란스러울 거다... 전부 true(참) 이 나온다.

 

왜일까?

이것도 마찬가지이다.

 

stringBool 이란 변수는 문자열 'false'를 가진 그냥 변수이다. 즉, 문자열 변수...

그러므로 이걸 Boolean 형 변환시킨다고 하면 자바스크립트는 문자열 그대로 변환시키는 게 아니라,

 

 stringBool 이 'false'라는 문자열 데이터를 가진 변수가 참이냐 거짓이냐를 판별하는 것이다.

즉, stringBool 이 'false' 든 'true' 든 어떤 문자열이든 상관없이 stringBool 변수 자체를 참이냐 거짓이냐로 보는 거기 때문에, 그래서 형 변환하면 true 가 나오는 것이다.

 

stringNum 도 마찬가지고, stringSpace 도 마찬가지이다.

 

 

이제 다른 예제를 봐보자.

var obj = {};
var arr = [];
var func = function(){};


console.log(Boolean(obj)); // ???
console.log(Boolean(arr));  // ???
console.log(Boolean(func)); // ???

 

이 경우는 어떤가?

이것도 전부 형 변환을 하면 true 나온다.

 

이유는?

이 전이랑 이유가 똑같다.

 

즉, obj, arr, func는 전부 빈 데이터를 가지고 있지만 객체, 배열, 함수 이렇게 선언된 실질적으로 존재하는 객체들이기 때문에 형 변환을 시도하면 전부 true가 나오는 것이다.

반응형

+ Recent posts