JavaScript的隐式类型转换

  1. 隐式转换规则
  • 转成string类型: + (字符串拼接符)
  • 转成number类型:++、--、+、-、*、/、%、<、>、<=、>=、!= 、== 、!== 、===
  • 转成boolean类型:!(逻辑非运算符)
  1. 字符串连接符+:只要+两边有一边是字符串,会吧其他数据类型调用String()方法转换成字符串然后拼接

  2. 算数运算符+:+两边都是数字,会把其他数据类型调用Number()方法转换成数字然后进行假发运算

  3. 关系运算符:会把其他数据类型转换成number之后再作比较:

  • 1.当关系运算符两边有一边是字符串的时候,会把字符串转换成number然后比较,比如'a' > 10返回false,'a'<10也返回false,因为Number('a')=NaN

  • 2.a. 当关系运算符两边都是字符串的时候,会根据unicode编码来判断,'2' > '10'返回true,因为'2'.charCodeAt()=50, '10'.chaeCodeAt()=49(默认返回第一个字符的编码,如果想要查询第二个字符可以传参下标); b. 多个字符从左向右依次比较;

  • 3.特殊情况,如果数据类型是undefined或者null,得出固定结果

  • 4.特殊情况,NaN和任何数据比较都是false,包括NaN;

  • 5.复杂数据类型:在隐式转换时会先转成string,然后再转成Number
    image

    • a.先使用valueOf()方法获取原始值,如果原始值不是number类型,则使用toString()方法转成string;
    • b.再将string转成number(unicode码)运算
console.log([1, 2] == '1,2');//true, 先获取数组的原始值,然后转成string,然后通过左右两边的字符串的unicode编码运算
console.log([1, 2].valueOf());//[1, 2]
console.log([1, 2].valueOf().toString());//'1,2'

var a = {};
console.log(a == "[object Object]");//true
console.log(a.valueOf().toString());//"[object Object]"

//声明一个变量a,使下面表达式打印1
var a = {
    i: 1,//声明一个属性i
    valueOf: function(){
        return a.i++;//每调用一次valueOf,让自增1,并且返回i的值
    }
}
if(a == 1 && a ==2 && a == 3){
    console.log(1)
}

  • 6.逻辑非隐式转换与关系运算符隐式转换
    **注意:**空数组的toString()方法会得到一个空字符串,而空对象的toString()方法会得到字符串[object Object]

    • a.关系运算符:将其他数据类型转成number
    • b.逻辑非!:将其他数据类型使用Boolean()转成布尔值
      • 1.null,undefined,空字符串,0,-0,NaN,false,document.all()转布尔值都会得到false,除此之外全都是true
      • 2.逻辑非运算符优先级高于关系运算符,所以要先得到逻辑非运算结果在进行比较
console.log([] == 0)//true,
//原理:[].valueOf().toString() => "", Number('') == 0

console.log(![] == 0);//true
//原理:逻辑非优先级高于关系运算符,空数组不在上面八种情况里,所以空数组转成布尔值应该是true,![] => false,false == 0成立

console.log({} == !{});//false
console.log({} == {});//false
//原理:
//1:本质上是{} 与 !{}这个逻辑非表达式比较,!{} => false,{}.valueOf().toString() => '[object Object]', 所以{} == !{}不成立,返回false
//2:引用数据类型存储在堆中,栈中存储的是引用地址,所以返回false

console.log([] == ![]);//true
console.log([] == []);//false
//原理:
//1:本质上是比较[]和![]逻辑非运算结果,[].valueOf().toString() => '',Number('') => 0,![] => false, 0 == false成立,返回true;
//2:引用数据类型,false