为啥要说这个东西?
一道面试题就给我去说它的动机.
题如下:
javascript 代码
- var bool = new Boolean(false);
- if (bool) {
- alert('true');
- } else {
- alert('false');
- }
运行结果是 true!!!
其实啥类型转换啊, 操作符优先级啊, 这些东西都是最最基本的.
犀牛书上有详细的介绍. 但我很少去翻犀牛书的前 5 章...
比如说优先级那块儿, 很多书都教育我们,"不用去背诵优先级顺序, 不确定的话, 加括号就行了."
平常我们写代码时也确实这么做的.
但现实是啥呢? 面试时会出这种题, 让你来做...
真不知道这种题的意义是啥...
抱怨到此为止, 本文尝试来解决类型转换问题, 争取把JS 权威指南49 页那个表背下来.
都有哪些东西是假值?
共 6 个:
[quote]0 或 + 0,-0,NaN
- ""
- false
- undefined
- null[/quote]
上面的顺序是按照基本类型来排列的.
除此之外的一律不是!! 哪怕是如下形式:
- [quote]Infinity
- '0','false'," "(空格字符)
任何引用类型:[],{},function(){}[/quote]
if (a && b) 的正确理解方式是: a && b 进行表达式求值后, 然后再转换为 Boolean 类型.
&& 是种短路语法, 求值后不一定是个 Boolean 类型, 更不是两边转化布尔值再运算.
比如 2&&3 的结果是 3, 不是 true.
所以 if(a && b), 我们平常理解的那种,"如果 a 和 b 同时为真的话", 是一种错误的描述方式.
其他基本类型转化为字符串, 基本和预期的一样:
javascript 代码
- console.log(""+ null); //"null"console.log("" + undefined); // "undefined"
- console.log(""+ false); //"false"console.log("" + true); // "true"
- console.log(""+ 0); //"0"console.log("" + NaN); // "NaN"
- console.log(""+ Infinity); //"Infinity"
其他基本类型转化为数字, 需要特殊记忆:
javascript 代码
- console.log(+null); // 0
- console.log(+undefined); // NaN
- console.log(+false); // 0
- console.log(+true); // 1
- console.log(+""); // 0
- console.log(+'1'); // 1
- console.log(+'1x'); // NaN
其中 null, 空字符是 0,undefined 是 NaN.
以上, 基本类型转换都说明白了.
下面来看看引用类型转换为基本类型.
引用类型转换为布尔, 始终为 true
引用类型转换为字符串
[quote]1. 优先调用 toString 方法 (如果有), 看其返回结果是否是原始类型, 如果是, 转化为字符串, 返回.
2. 否则, 调用 valueOf 方法 (如果有), 看其返回结果是否是原始类型, 如果是, 转化为字符串, 返回.
3. 其他报错.[/quote]
引用类型转化为数字
[quote]1. 优先调用 valueOf 方法 (如果有), 看其返回结果是否是基本类型, 如果是, 转化为数字, 返回.
2. 否则, 调用 toString 方法 (如果有), 看其返回结果是否是基本类型, 如果是, 转化为数字, 返回.
3. 其他报错.[/quote]
首先我们看看常见引用类型 toString 和 valueOf 返回什么?
- [quote]var a = {};
- console.dir(a.toString()); // "[object Object]"
- console.dir(a.valueOf()); // 对象本身
- var b = [1, 2, 3];
- console.dir(b.toString()); // "1,2,3"
- console.dir(b.valueOf()); // 对象本身
- var c = [[1],[2]];
- console.dir(c.toString()); // "1,2"
- console.dir(c.valueOf()); // 对象本身
- var d = function() {return 2};
- console.dir(d.toString()); // "function() {return 2}"
- console.dir(d.valueOf()); // 对象本身 [/quote]
因此对应的转换为字符串和数字的情形是:
- [quote]var a = {};
- console.dir(a + ""); //"[object Object]"
- console.dir(+a); // NaN
- var b = [1, 2, 3];
- console.dir(b + ""); //"1,2,3"
- console.dir(+b); // NaN
- var c = [[1],[2]];
- console.dir(c + ""); //"1,2"
- console.dir(+c); // NaN
- var d = function() {return 2};
- console.dir(d + ""); //"function () {return 2}"
- console.dir(+d); // NaN[/quote]
再来个报错的情形:
- [quote]var a = {};
- a.toString = function() {return {};}
- console.log("" + a); // 报错
- console.log(+a) // 报错 [/quote]
以上类型转换规律基本说完.
最后来说一下万恶的 "=="
面试题如下:
javascript 代码
- var a = false;
- var b = undefined;
- if (a == b) {
- alert('true');
- } else {
- alert('false');
- }
本以为会弹出 true 的. 天那! 为啥是 false?
哈哈...
双等号, 如果两边类型不同, 会有隐式转换发生. 犀牛书 75 页总结如下:
[quote]1,null 和 undefined, 相等.
2, 数字和字符串, 转化为数字再比较.
3, 如果有 true 或 false, 转换为 1 或 0, 再比较.
4, 如果有引用类型, 优先调用 valueOf.
5, 其余都不相等.[/quote]
因此有:
- [quote]console.log(undefined == false); // false
- console.log(null == false); // false
- console.log(0 == false); // true
- console.log(NaN == false); // false
- console.log("" == false); // true[/quote]
0 == false 之所以为 true 根据第 3 条.
""== false 之所以为 true 根据第 3 条, 变成了"" == 0, 再根据第 2 条.
第 4 条再来一个例子:
console.log([[2]] == 2)
其上结果为 true, 原因如下:
[[2]] 的 valueOf 是对象本身, 不是基本类型.
尝试调用 toString 的结果是'2'.
因此变成了'2'和数字 2 的比较. 根据第 2 条, 相等. WTF!!
最后说句, 使用 "===" 就没有这些问题了.
本文完.
来源: http://www.qdfuns.com/article/17398/a9565882bb31781fd7878786e46ce294.html