目录
隐式类型转换
非String转换为String的规则:String()
- null:转为"null"
- undefined:转为"undefined"
- Boolean:true和false分别被转为"true"和"false"
- Number:转为数字的字符串形式,如10转为"10", 1e21转为"1e+21"
- 数组:转为字符串是将所有元素按照",“连接起来,相当于调用数组的Array.prototype.join()方法,如[1, 2, 3]转为"1,2,3”,空数组[]转为空字符串,数组中的null或undefined,会被当做空字符串处理
- 普通对象:转为字符串相当于直接使用Object.prototype.toString(),返回"[object Object]"
非Number转换为Number:Number()
- null: 转为0
- undefined:转为NaN
- String:如果是纯数字形式,则转为对应的数字,空字符转为0, 否则一律转为NaN
- Boolean:true和false被转为1和0
- 数组:数组首先会被转为原始类型,然后根据转换后的原始类型按照上面的规则处理
- 对象:同数组
非Boolean转换为Boolean:Boolean()
空字符串(""),数字0(0),undefined,null,false本身,NaN的隐式类型转换都为false 其余转为true
对象类型转换为原始类型
- 原始类型:Undefined、Null、Boolean、Number 和 String
- 先查找对象的valueOf()方法,如果valueOf()方法返回原始类型的值,则原始类型的值就是这个值
- 如果valueOf()不存在或者valueOf()方法返回的不是原始类型的值,就会尝试调用对象的toString()方法,即遵循上述的
非String转换为String的规则
,然后使用toString()的返回值作为原始类型的值。 - 如果valueOf()和toString()都没有返回原始类型的值,则会抛出异常。
console.log(Number([]))// 0 数组会先调用valueOf(),但返回的是数组本身,不是原始类型,所以会继续调用toString(),得到空字符串,相当于Number(''),所以转换后的结果为"0"
console.log(Number(['10']))// 10 同理,Number(['10'])相当于Number('10'),得到结果10
==
比较两个数据是否相等,会发生隐式类型转换。
Boolean==其他类型
Boolean转Number 再进行比较 根据上述非Number转换为Number规则
Boolean:true和false被转为1和0
console.log(1 == true);// true 1=1
console.log(2 == true);// false 2!=1
Number==String
String转Number 再进行比较 根据上述非Number转换为Number规则
String:如果是纯数字形式,则转为对应的数字,空字符转为0, 否则一律转为NaN
0 == '' // true
1 == '1' // true
1e21 == '1e21' // true
Infinity == 'Infinity' // true
// 下面的例子中 Boolean转Number String转Number 再进行比较
true == '1' // true
false == '0' // true
false == '' // true
对象类型==原始类型
根据上述对象类型转换为原始类型规则
进行转换再比较
'[object Object]' == {} // true
'1,2,3' == [1, 2, 3] // true
[2] == 2 // true [2].valueOf()返回[2] [2].toString返回'2' '2'与2比较时 '2'转为2 所以true
[null] == 0 // true
[undefined] == 0 // true
[] == 0 // true
console.log([] == true);// false
对象类型==对象类型
对于引用数据类型 比较的是地址值
console.log([]==[]); // false
null、undefined和其他类型的比较
console.log(null == undefined)// true
console.log(null == null)// true
console.log(undefined == undefined)// true
除此之外 null/undefined==其他类型 全为false
NaN和任何值都不相等 包括它自己
===
比较两个数据是否相等,除了比较原始值,还会比较两个数据的类型,即不会发生隐式类型转换。
isNaN
1.NaN表示not a number,即不是数字。所有经过Number()方法转换得到NaN的数据,用isNaN来判断结果都是true。
2.0 除以0会返回NaN 但是其他数除以0则不会返回NaN。
console.log(isNaN(0/0));// true
console.log(isNaN(1/0));// false
3.如果isNaN函数的参数不是Number类型, isNaN函数会首先尝试将这个参数转换为数值,然后才会对转换后的结果是否是NaN进行判断。因此,对于能被强制转换为有效的非NaN数值来说(空字符串和布尔值分别会被强制转换为数值0和1),返回false值也许会让人感觉莫名其妙。这是由于isNaN函数其实等同于回答了这样一个问题:被测试的值在被强制转换成数值时会不会返回IEEE-754中所谓的“不是数值(not a number)”。
4.es6将isNaN非法放入Number上,并且不会发生隐式类型转换(Number.isNaN(‘1’)结果是false),与全局的isNaN方法行为不一致。
5.通过Number.isNaN(x)来检测变量x是否是一个NaN将会是一种可靠的做法。在缺少Number.isNaN函数的情况下, 通过表达式(x != x) 来检测变量x是否是NaN会更加可靠。
6.如果isNaN(x)返回false,那么x在任何算数表达式中都不会使表达式等于NaN;如果返回true,x会使所有算数表达式返回NaN。实际上, isNaN(x), isNaN(x - 0),isNaN(Number(x)), Number.isNaN(x - 0),和Number.isNaN(Number(x)) 的返回值都是一样的,都是true
7.isNaN的作用:可以用来检测函数的参数是否是可运算的(可以像number一样进行加减乘除等运算)。如果不可运算,则可赋予这个参数一个默认的值或其他合适的内容。
function increment(x) {
if (isNaN(x)) x = 0;// 若传进来的实参x不是一个数 则x = 0
return x + 1;
};
8.isNaN例子:
isNaN(true); // false 布尔值true会转为非0值
isNaN(false); // false 布尔值false会转换成0
isNaN(null); // false null会转为0
// strings
isNaN("37"); // false: 可以被转换成数值37
isNaN("37.37"); // false: 可以被转换成数值37.37
isNaN("37,5"); // true "37,5"不能转换为数值
isNaN('123ABC'); // true:parseInt("123ABC") = 123, 但是Number("123ABC") = NaN
isNaN(""); // false: 空字符串被转换成0
isNaN(" "); // false: 包含空格的字符串被转换成0
isNaN(new Date()); // false 会转换成当前的时间
isNaN(new Date().toString()); // true
isNaN([]); // false []转换成0
isNaN(new String()); // false
isNaN(new Array()); // false
isNaN("Infinity"); // false:"Infinity"转换为Infinity
isNaN(-0.1); // false
isNaN(x) == isNaN(Number(x)) // 不论x为何值 都返回true 哪怕x = undefined
// 因为isNaN(undefined) = true 且 Number(undefined) = NaN 使得isNaN(NaN) = true
isNaN() == isNaN(Number()) // false, because isNaN() = true and Number() = 0
//以下全部返回true
isNaN({}); // 空对象执行toString方法 结果是'[object Object]'
isNaN(String); //
isNaN(Array); //
isNaN("blabla"); // "blabla"不能转换成数值
isNaN("-blabla"); //
isNaN(0/0); //
isNaN("0/0"); // "0/0"不能转换成数字
isNaN(Infinity/Infinity); //
isNaN(NaN); //
isNaN(undefined); //
isNaN();
Object.is
1.Object.is()的用法与全等===基本一致,唯有不同的两点:
- 0和+0是一样的 但是0和-0是不一样的
- NaN与NaN为true
Object.is(0, -0); // false
Object.is(+0, -0); // false
Object.is(0, +0); // true
Object.is(NaN, 0/0); // true
2.Object.is() 的实现原理
Object.is = function(x, y) {
if (x === y) {
// 1/+0 = +Infinity, 1/-0 = -Infinity, +Infinity不等于-Infinity
return x !== 0 || 1 / x === 1 / y;
}
// 一个变量不等于自身变量,那么它一定是 NaN
// 两个都是NaN的时候返回true
return x !== x && y !== y;
};