var a = 42;
var b = a + ""; // 암시적 강제변환
var c = String(a); // 명시적 강제변환
어떻게 값이 문자열, 숫자, 불리언 등의 타입이 되는지 그 기본 규칙!!
ToString
- ‘문자열이 아닌 값 -> 문자열’ 변환 작업은 ToString 추상 연산 로직이 담당한다. 내장 원시 값은 본연의 문자열화 방법이 정해져 있다.
- 일반 객체는 특별히 지정하지 않으면, 기본적으로 Object.prototype.toStirng() 메서드가 내부 [[Class]]를 반환한다. (“[object Object]”)
- 자신의 toString() 메서드를 가진 객체는 prototype연쇄를 따라기 전에 먼저 자신의 toString()메서드를 사용하므로, 이 메서드가 기본 호출되어 toString()을 대체한다.
- 배열은 기본적으로 재정의된 toString()이 있다. 문자열 변환 시 모든 원소 값이 콤마(,)로 분리된 형태로 이어진다.
var a = [1, 2, 3]; a.toString(); // "1, 2, 3"
JSON.stringify(undefined); // undefined
JSON.stringify(function(){}); // undefined
JSON.stringify(
[1, undefined, function(){}, 4]
); // "[1, null, null, 4]"
JSON.stringify(
{ a: 2, b: function(){} }
); // "{"a":2}"
var o = {};
var a = {
b: 42,
c: o,
d: function(){}
};
// 'a'를 환형 참조 객체로 만든다.
// a.c.e === a
o.e = a;
// 환형 참조 객체는 JSON 문자열화 시 에러가 난다.
// JSON.stringify(a);
// toJSON 함수가 호출되는 호출부가 a이므로 this는 a
a.toJSON = function() {
// 직렬화에 프로퍼티 'b'만 포함시킨다.
return { b: this.b };
};
JSON.stringify(a); // "{"b":42}"
var a = {
valueOf: function() {
return "42";
}
};
var b = {
toString: function() {
return "42";
}
}
var c = [4, 2];
c.toString = function() {
return this.join(""); // "42"
}
Number(a); // 42
Number(b); // 42
Number(c); // 42
Number(""); // 0
Number([]); // 0
Number(["abc"]) // NaN
var a = 42;
var b = a.toString();
var c = "3.14";
var d = +c;
b; // "42";
d; // 3.14;
+
단항 연산자가 사용된다.
var d = new Date("Mon, 18 Aug 2014 08:53:06 CDT");
+d; // 1408369975000
// 다음과 같이 현재 시각을 타임스탬프로 바꿀 때 관용적으로 사용하는 방법이다.
var timestamp = +new Date();
// 하지만 이 방법이 더 좋다.
var timestamp = new Date().getTime();
// 그리고 이 방법이 제이이이이이이이일 좋다!!
var timestamp = Date.now();
Date.now()
로, 그 외 특정 날짜/시간 타임스탬프는 new Date().getTime()
을 대신 쓰도록 하자|
혹은 ~
를 사용하면 강제 벼환 효과가 있다.~
연산자는 먼저 32비트 숫자로 강제변환한 후 NOT 연산을 한다. (각 비트를 거꾸로 뒤집는다. - 보수 구하기)
~42; // -(42+1) ==> -43
indefOf()
를 정의할 때 이 전례를 따라 특정 문자를 발견하지 못했을 때 -1을 반환한다.
var a = "Hello World";
~a.indexOf("lo"); // -4
~~
는 ~
를 두번 사용해 원래 상태로 돌리지만 ToInt32강제변환은 되어있다. (잘라내기)Math.floor()
는 버림 - 작은 값으로)x|0
보다 높다. (속도는 느리다)Boolean()
은 명시적이지만 자주 쓰이지 않는다.!!
이중부정 연산자를 사용한다.Boolean()
이나 !!
를 쓰지 않으면 if()
문 등의 불리언 콘텍스트에서 암시적인 강제변환이 일어난다.부수 효과가 명확하지 않게 숨겨진 형태로 일어나는 타입변환
암시적 강제변환의 목적은 중요한 내용으로부터 주의를 분산시켜 코드를 잡동사니로 가득 채워버리는 장황함, 보일러플레이트, 불필요한 상세 구현을 줄이는 것이다.
- 숫자는 공백 문자열 ““와 더하면 간단히 문자열로 강제변환된다. ```javascript var a = 42; var b = a + “”;
b; // “42”
- 위의 코드는 명시적 강제변환 String(a)에 비해 유의할 점이 있다.
- `a + ""`는 a 값을 ToPrimitive 추상 연산과정에서 `valueOf()` 메서드에 전달하여 호출하고, 그 결과값은 ToString 추상 연산을 하여 최종적인 문자열로 변환한다.
- `String()`메서드는 `toString()`을 직접 호출하는 것일 뿌닝다.
```javascript
var a = {
valueOf: function() { return 42; },
toString: function() { reutrn 4; }
};
a + ""; // "42"
String(a); // "4"
&&
연산자와 ||
연산자의 결괏값이 반드시 불리언 타입이어야 하는 것은 아니면 항상 두 피연산자 표현식 중 어느 한쪽 값으로 귀결된다.
var a = 42;
var b = "abc";
var c = null;
a || b; // 42
a && b; // "abc"
c || b; // "abc"
c && b; // null ####### false가 아닌 null!!!!!!!
// 이유!!!
// 아래 두개는 같다.
a || b;
a ? a : b;
// 아래 두개는 같다.
a && b;
a ? b : a;
var a = "42";
var b = true;
a == b; // false
느슨한 동등비교인데 (===가 아니다) 왜 false이지…?
==
d연산과는 전혀 무관하다!==
의 피연산자 한쪽이 불리언 값이면, 예외 없이 그 값이 먼저 숫자로 강제변환된다.var a = "42";
if (a == true) {
// fail!!
}
if (a === true) {
// also fail!!
}
if (a) {
// not bad (success)
}
if (!!a) {
// good!! (success)
}
null
과 undefined
를 느슨한 동등비교(==
)하면 서로에게 타입을 맞춘다.(강제변환한다)var a = null;
var b;
a == b; // true
a == null; // true
b == null; // true
a == false; // false
b == false; // false
a == ""; // false
b == ""; // false
a == 0; // false
b == 0; // false