原始值转原始值
转字符串
String(undefined); // -> 'undefined'String(null); // -> 'null'String(3); // -> '3'String(true); // -> 'true'String(false); // -> 'false'
转数字
Number()方法转换数字时,如果出现非数字的字符时会直接返回NaN(null 、布尔值除外),且可以识别浮点数。parseInt()方法,首先是可以将数字或者字符串转换成为一个整数数字,如果字符串的第一个字符不能被转换为数字,直接返回NaN;字符串中出现不能转为数字的字符,该方法会进行截取操作。方法还有第二个参数(可选),表示要解析数字的基数,介于2~36之间。(该篇主要讨论数据类型的转换,所以在此不做过多介绍。)
Number(undefined); // -> NaNNumber(null); // -> 0Number('3'); // -> 3Number('.3'); // -> 0.3Number('1 3'); // -> NaNNumber('3a'); // -> NaNNumber('a3'); // -> NaNNumber(true); // -> 1Number(false); // -> 0Number(''); // -> 0parseInt(undefined); // -> NaNparseInt(null); // -> NaNparseInt('3'); // -> 3parseInt('.3'); // -> NaNparseInt('0.3'); // -> 0parseInt('3 1'); // -> 3parseInt('3a'); // -> 3parseInt('a3'); // -> NaNparseInt(true); // -> NaNparseInt(false); // -> NaN
转布尔值
这里就涉及到一个虚值(falsey)的概念
虚值:undefined、null、0、false、NaN、’’。(注意''和' '可不一样,空格属于一个字符)
只要是虚值转换布尔值都为false,反之都为true。
Boolean(' '); // -> trueBoolean(''); // -> falseBoolean(undefined); // -> falseBoolean(null); // -> falseBoolean(0); // -> falseBoolean(false); // -> falseBoolean(NaN); // -> false
引用类性值转原始值
引用类性值转数字
- 首先通过
valueOf()方法,看其返回值是否是原始值。 - 如果为原始值,直接通过
Number()方法转换为数字。 - 如果是非原始值,则调用其对应类型的
toString()方法(基于原型链查找)。 - 如果返回的值是原始值,直接通过
Number()方法转换为数字。 如果通过重写
toString()更改了返回值,返回的是一个对象的话,直接报错。注意:
valueOf()方法,如果没有被我们重写的话,默认返回的就是自身。Number({});// {}.valueOf() -> {} -> {}.toStirng() -> '[object Object]'// -> Number('[object Object]') -> NaNNumber([]);// [].valueOf() -> [] -> [].toStirng() -> '' -> Number('') -> 0Number(function () {});// (function () {}).valueOf() -> (function () {}).toString() -> 'function () {}' -> Number('function () {}') -> NaN
引用类性值转字符串
先通过
toString()方法, 看其返回值是否是原始值。- 如果是原始值,调用其包装类所对应的
toString()方法。 - 如果是重写的
toString()返回的是引用类型值,则调用valueOf()方法。 - 如果返回原始值,调用其包装类所对应的
toString()方法。 - 如果还是引用类型值,直接报错。 ```javascript // 这种两种转换方式是等效的 String([]) === ‘’ + [];
String(undefined); // -> ‘undefined’ String(null); // -> ‘null’
var obj = { toString () { return []; }, valueOf () { return {}; } } String(obj); // 报错 Uncaught TypeError: Cannot convert object to primitive value at String
var obj1 = { toString () { return []; }, valueOf () { return 3; } } String(obj1); // -> ‘3’
var obj2 = { toString () { return true; }, valueOf () { return 3; } } String(obj2); // -> ‘true’
<a name="wrpUg"></a>## 双等隐式转换规则引用类型值和原始类型值进行比较时,都通过`Number()`方法转为数字后进行比较。<br />两个引用类性值比较时,会根据指针(栈内存中的引用地址)进行对比。<br />特例:<br />`undefined == null // -> true`,undefined 和 null 除了彼此相等和自己相等之外,与其他任何类型的值都不相等。<br />`NaN == NaN // -> false`,NaN 与任何值都不相等包含自己本身。```javascriptundefined == null // -> trueNaN == NaN // -> false// questionconsole.log([] == ![]);console.log({} == !{});/*** "!" 逻辑运算符 优先级 17* !expr 若 expr 可转换为 true, 则返回 false;否则, 返回 true* "==" 比较运算符 优先级 11* 相等比较操作符会为两个不同类型的操作数转换类型*//*** [] == ![]* 先运算 ![] []不是一个虚值, 转布尔值就为true, !true -> false;* [] == false* [] -> [].valueOf() -> [] -> [].toString() -> '' -> Number('') -> 0* false -> Number(false) -> 0* 0 == 0 -> true*//*** {} == !{}* 先运算 !{} {}不是一个虚值, 转布尔值就为true, !true -> false;* {} == false* {} -> {}.valueOf() -> {} -> {}.toString() -> '[object Object]' -> Number('[object Object]') -> NaN* false -> Number(false) -> 0* 0 == NaN -> false*/
