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