隐式转换的规则
转换为String类型:+ (字符串连接符)转换为Number类型: ++/–(自增自减)+、-、*、/、%(算术运算符)>、 < 、>= 、<=、 == 、!=、 === 、!=== (关系运算符)转换为boolean类型:!(逻辑非运算符)隐式转换例子
字符串连接符与算术运算符隐式转换规则混淆 console.log(1+"true");//1true 分析:Number类型的数据与String类的数据用+连接此时+为字符串连接符号,将1用toString方法转换为String类型数据连接,所以为1true console.log(1+true);//2 分析:Number类型数据与非字符类型的数据用+连接,将其他类型的数据调用Number方法转换后相加,true为1所以1+1 = 2 console.log(1+undefined);//NaN 分析:undefined转换为数字类型的数据为NaN类型的数据,任何与NaN运算的数据结果都为NaN console.log(1+null);//1 分析:null转为数字类型的数据为0,0+1 = 1 关系运算符:会把其他数据类型转换成number之后再比较关系 console.log("2">10);//false 分析:当Number类型的数据与String类型的数据进行关系运算将String类型的数据转换为Number类型的数据运算, 2 < 10 所以为 false console.log("2">"10");//true 分析:当两个String类型的数据进行关系运算时,同时转换为Number类型的数据进行比较,但是这个Number类型的数据为字符串对应的unicode编码,使用Str.charCodeAt()来获取。 "2" => 50 "10" => 49 50 > 49 所以为 true console.log("abc">"b");//false console.log("abc" > "aab");//true 分析:当两个String类型的数据长度不一致时,从左到右逐位比较。 str1 = "abc" ,str2 ="b" str1和 str2的第一位字符不一致所以直接比较第一位字符即可。 "a" => 97 "b" => 98 97 < 98 所以为false str1 ="abc", str2 = "aab",str1 和 str2 的第一位字符一致,比较第二位字符即可。 "a" => 97 "b" => 98 97 < 98 所以为true console.log(NaN == NaN);//false 分析:NaN和任何类型的数据比较都是NaN 即 false console.log(undefinden == null);//true 分析:特殊情况下 undefined == undefined //true undefined === undefined //true undefined == null //true undefined === null //false null == null // true null === null //true复杂数据类型在隐式转换时会先转成String,然后再转成Number运算
复杂数据类型转换为number顺序如下 使用valueOf()方法获取原始值,原始值不为Number类型,使用toString()方法转换为String将String类型数据转换为Number类型的数据 console.log([1,2] == '1,2');//true 分析: [1,2].valueOf() =>[1,2] =>[1,2].toString() => '1,2'; '1,2' 和 '1,2'的unicode编码值一致所以为true var a = {}; console.log(a == "[object Object]");//true 分析: {}.valueOf() => [object Object] => [object Object].toString() => "[object Object]" 两边的unicode编码值一致所以为true var a = { i:0, valueOf:function(){ return ++this.i; } } if(a == 1 && a == 2 && a == 3){ console.log("1"); } 分析: 复杂数据类型在进行关系运算时都会调用一次valueOf()方法所以可以重写valueOf()方法,让其将 i 的属性自增返回,这样每次进行关系运算时 都会使得 a.i的值自增 所以a的值就可以变为 1,2,3满足判断条件逻辑非隐式转换与关系运算符隐式转换搞混淆
空数组的toString()得到空字符串,空对象的toString()得到"[object Object]"关系运算符:将其他数据类型转换为数字类型逻辑非:将其他数据类型转换为布尔类型 以下情况为false其他都为true 0、-0、NaN、undefined、null、" "、false、document.all() console.log([] == 0);//true 分析:[].valueOf().toString() =>"" => Number("") => 0 0 == 0 所以为true console.log(![] == 0 );//true 分析: 逻辑运算符优先级高于关系运算符,所以为 ![] 与 0比较 Boolean([]) => true !true => false => Number(false) => 0 0 == 0 所以为 true console.log([] == ![]);//true 分析: [].valueOf().toString() =>"" => Number("") => 0 Boolean([]) => true !true => false => Number(false) => 0 0 == 0 所以为true console.log([] == []);//false 分析:引用型数据存储在堆中,两者比较的是地址,地址不一致所以是不一样的为false console.log({} ==!{});//fasle 分析: {}.valueOf().toString() => '[object Object]' => Number("[object Object]") => 1 Boolean({}) => true => Number(!true) = > 0 1 != 0 所以为 false console.log({} == {});//fasle 分析:引用型数据存储在堆中,两者比较的是地址,地址不一致所以是不一样的为false