开头先给大家一个题目思考,答案在结尾揭晓。
if (a ==2 && a == 3) { //...true } [null] == "";
首先为什么使用”==“运算符,假设我们需要在想要新建一个Object.is的函数,我们首先会怎么做,是不是判断一下这个方法是不是存在。 如果用严格相等运算符“===”,我们要怎么写?
if (typeof Object.is !== 'function') { Object.is = function(x, y) { if (x === 0 && y === 0) { return 1 / x === 1 / y; } if (x !== x ) { return y !== y; } return x === y; } }
如果我们用 “==”,怎么写呢?
if (!Object.is) { //... }
是不是简洁了许多 ,当我们需要显示的类型转化的时候就使用 “==”运算符。
下面就是转化规则,分为四部分可以相互嵌套使用,首先先说一下特殊情况: +0等于-0; NaN不等于自身。
1.如果数字和字符串进行 (==) 比较时候,将字符串转化为数字进行比较。
123 == '123'; //true 123 == Number('123');
2.一边是布尔型,一边是其他类型,将布尔转化为数字进行 (==) 比较。
'
'42' == true; //false '42' == Boolean(true);
首先将true转化为数字,之后根据规则(1)
42 == 1;
所以在写判断条件的时候,不要轻易使用 (==) true。
var a = 42; if (a == true) { }
3.undefined == null
这条规则比较简单,undefined在 == 运算符下只和null返回true,其他一律为false。
null == false; null == true; null == ''; null == 0; undefined == true; undefined == false; undefined == ''; undefined == 0;
4.对象与基本类型比较。
首先非对象全部会被转化为基本类型,之后根据上述规则比较 ;
对象转化为基本类型,首先调用valueOf,如果转化结果为对象,继续调用toString,如果返回的不是基本类型,会报错。
[42] == 42; //true 'abc' == new String('abc'); //true
这里需要注意一点Object(null || undefined)会返回一个空对象,在使用 (==) 时需谨慎。
'abc' == new String(null); //false
根据对象转化,我们自定义返回的值,比如:
var a = []; a.valueOf = function() { return 42; }; a.toString = function () { return '123'; }; a == 42; //true
常见误区:
1.
[] = ![]; //true
这里会返回true的原因很简单,因为(!) 是强制转化,将true转化为false,这里的 [] 是对象,返回的true,之后使用 ! 返回false.
根据上面规则,布尔值进行 == 比较时会转化为数字比较。
也就是
"" == 0
2. 0 == '\n' //true
这里会返回true,因为空格和一些其他制表符会被忽略掉。
再来看一些常见的。
'0' == false; //true false == 0; //true false == ''; //true false == []; //true '' == []; //true 0 == []; //true'' == 0; //true
最后: 如果 (==)一边出现了true或者false不要使用 (==) 操作符;
如果 (==) 一边带有 "[]" ,"", "0",也尽量不要使用操作符。
回到一开始答案,我们可以在对象上定义valueOf属性,然后让他递增,
实现a ==2 && a == 3;
var i = 2; var a = new Number(); a.valueOf = function () { return i++; }; if (a == 2 && a == 3) { console.log('yes'); }
再来看[null] == "",可能你在想[null]返回的不就是字符串“null”么,不过很遗憾,null和undefined,在数组中转化为字符串为“”,这是JavaScript所规定的。
[null] == ""; "" == "";