JavaScript中的隐式转化之相等判断过程中的隐式转化

目录

1.什么是隐式转化?

2.隐式转换规则

3.不同类型 比较 或 运算 时的隐式转换规律

4.对象 进行数据类型转换的过程

 5.一些基本规律

6."==" 相等/宽松相等/抽象相等

7."==="  全等/严格相等

 8.案例

 9.常见的 "==" 关系表


1.什么是隐式转化?

在JavaScript中,当运算符在运算时,如果运算符两边数据不统一数据类型,计算机底层CPU就没办法计算。所以编译器就会自动将运算符两边的数据做一个数据类型转化,转成一样的数据类型再进行计算(一般转化为数字型,因为计算机底层是以二进制数据进行计算)。这种无需程序员手动操作,编译器自动转换的方式就称为隐式转换。

eg:2 > "3" 结果为?

分析:"3"转换为数值型为 3,2 > 3结果为false

2.隐式转换规则

1.转换为string类型: + (字符串连接符) 

        若运算符+ 两端都是数值型,就是正常的加法运算

        若运算符+两端含有字符串型,就会把数据类型转为字符串,再进行拼接

2.转换为number类型:++  --   算术运算符(+,-,*,/,%,**),关系运算符(>,<,>=,<=,==,!=)

3.转换为boolean类型: !,!!(逻辑非运算符)

注意点: + 它既是连接符,也是运算符。当 + 两边都有值,且至少一个值是字符串类型时,就会转换为字符串类型,再进行字符串拼接。当只有 + 后面的值时,例如:+"456";等同于

Number("456"),会将字符串转换为数字456.

var a = +"123";
console.log(a);    // 123
console.log(typeof a); // number


 console.log(+undefined);  //NaN
 console.log(+null);       //0
 console.log(+true);       //1
 console.log(+false);      //0
 console.log(+'111');      //111
 console.log(+'11a');      //NaN

3.不同类型 比较 或 运算 时的隐式转换规律

 如上图:任意两种不同类型的值进行比较时(针对的是类型不同的),会按照上图方式进行相应的类型转换,例如:对象和布尔值比较的话,对象-->字符串-->数值,布尔值-->数值。然后两个数值进行比较。

那么具体对象是怎么转换为数值型的呢?

4.对象 进行数据类型转换的过程

1.先调用对象的 Symbol.toPrimitive 这个方法如果不存在这个方法(结果是undefined),目前已知的只有new Date()有这个方法,

2.再调用对象的 valueOf()获取原始值/基本数据类型,如果获取的不是原始值/没有得到基本数据类型,

3.再调用对象的 toString() 把其变成字符串

4.最后再把字符串调用 Number() 转换为数字 (结合 5.一些基本规律 来看

 eg: 结合例子理解:

console.log([] + 1); 
// [].valueOf()没有原始值,再调用 [].toString()得到 "",
//字符串遇到`+`运算符可以进行拼接,就不需要转成数字 => "1"
console.log([2] - true); 
// `[].valueOf()`没有原始值,再调用`[].toString()`得到`"2"`,
//再调用`Number("2")`得到数字2。true直接调用`Number(true)`得到1。最后2 - 1 => 1
console.log({} + 1); 
// `{}.valueOf()`没有原始值,再调用`{}.toString()`得到"[object Object]",
//遇到`+` 号进行字符串拼接 => "[object Object]1"
console.log({} - 1); 
// {}.valueOf()没有原始值,再调用`{}.toString()`得到"[object Object]",
//再调用`Number("[object Object]")`得到NaN,最后NaN - 1 => NaN

 5.一些基本规律

含字母(或其它字符 ,例如:","等)的字符串转换为数字型时,结果为NaN (NaN属于数字型),只含数字的字符串转为数字型时会转为该数字。

eg:举例说明 调用Number()函数
console.log(Number("undefined")); //NaN
console.log(Number("null"));      //NaN
console.log(Number("NaN"));       //NaN
console.log(Number("true"));      //NaN
console.log(Number("false"));     //NaN
console.log(Number("[object Object]")); //NaN
//特殊
console.log(Number(""));          //0

console.log(Number("123aaaa"));   //NaN
console.log(Number("aaa123aaaa"));//NaN
console.log(Number([2,3]));       //NaN  调用toString()得到"2,3" 含有其它字符,所以转为NaN

//只含数字的字符串
console.log(Number("1"));   //1
console.log(Number("0"));   //0
console.log(Number("-1"));  //-1
//注意点: Infinity(极大值) 和 -Infinity(极小值)都是属于数字型
console.log(Number("Infinity"));  //结果为数字型数据 Infinity
console.log(Number("-Infinity")); //结果为数字型数据 -Infinity

其它类型转换为数字型:

console.log(Number(true));     //1
console.log(Number(false));    //0
console.log(Number(null));     //0
console.log(Number(undefined));//NaN  重点

其它类型转换为布尔类型:

只有 0 ,NaN , null, undefined ,空字符串' ',false转为布尔类型时为false,其余情况转换为布尔类型都是true。且没有特殊情况

console.log(Boolean(0));         //false
console.log(Boolean(NaN));       //false
console.log(Boolean(null));      //false
console.log(Boolean(undefined)); //false
console.log(Boolean(""));        //false
console.log(Boolean(false));     //false

6."==" 相等/宽松相等/抽象相等

1、如果一个值是null,另一个是undefined,则它们相等。

2、如果一个值是数字,另一个是字符串,先将字符串转换为数字,然后使用转换后的值比较。

3、如果其中一个值是true,则将其转换为1再进行比较。如果其中一个值是false,则将基转换为0再进行比较。

4、如果一个值是对象,另一个值是数字或字符串,则将对象转换为原始值,然后再进行比较。对象通过toString()方法或valueOf()方法转换为原始值。JavaScript核心的内置类首先尝试使用valueOf(),再尝试使用toString(),除了日期类,日期类只使用toString()转换。那些不是JavaScript语言核心中的对象则通过各自的实现中定义的方法转换为原始值。

5、其他不同类型之间的比较均不相等.

一些特别的例子:

console.log(+0  ==  -0);        //true
console.log(null == undefined); //true
console.log(NaN == NaN);        //false
console.log(NaN != NaN);        //true
console.log(undefined == 0);    //false   因为undefined转为数字型为NaN
console.log(null == 0);         //false   重点且易错 看下面案例eg6

7."==="  全等/严格相等

基本数据比较类型和值,引用数据比较 类型/堆地址,是否相同。

1、如果两个值类型不相同,则它们不相等。

2、如果两个值都是null或者都是undefined,则它们不相等。

3、如果两个值都是布尔值true或false,则它们相等。

4、如果其中一个值是NaN,或者两个两个值都是NaN,则它们不相等NaN和其他任何值都是不相等的,包括它本身!!!通过!x==x来判断x是否为NaN,只有在x为NaN的时候,这个表达式的值才为true。

5、如果两个值为数字,且数值相等,则它们相等。如果一个为0,另一个为-0,则它们同样相等。

6、如果两个值为字符串,且所含的对应位上的16位数完全相等,则它们相等。如果它们的长度或内容不同,则它们不等。两个字符串可能含义完全一样且所显示出手字符也一样,但具有不同编码的16位值。JavaScript并不对Unicode进行标准化的转换,因此像这样的字符串通过"==="和"=="运算符的比较结果也不相等。

7、如果两个引用值同一个对象、数组或函数,则它们是相等的。如果指向不同的对象,则它们是不等的。尽管两个对象具有完全一样的属性

 8.案例

eg1:console.log([12] == 12); 结果为?

分析:结果为 true。 因为[12] 和 12 属于不同数据类型,先要转换为相同数据类型。

数组对象[12]按照对象转换规则,最后转为12, 所以 12 == 12 结果为true

eg2:"true" == true 结果为 ? 

分析:不同数据类型进行比较,会先转化为相同数据类型

"true" 转化为数字型为 NaN

true 转化为数字型为 1

所以 结果为false

eg3:为什么两个的结果都是true?(易错题) (结合5.一些规律来看)
console.log([] == false);  // true
console.log(![] == false); //true

分析:

数组对象[ ],没有Symbol.toPrimitive 这个方法,再调用valueOf(),没有得到基本数据,再调用toString();得到空字符串" ",再Number(""),结果为0,而false转为数字型也是0

所以 console.log([] == false); 结果为true

逻辑非!的操作步骤是: 先把[ ]转为布尔值,结果为true,再让其取反为false,所以就是false == false 结果为true。

eg4:console.log([[]] == false); 结果为?true

分析:结果为true  ;因为数组对象[[]]转换为字符串结果为"",再转为数字型,结果为0,false转为数字型结果为0 ,所以true

console.log([[]].valueOf()); //[Array(0)]
console.log([[]].toString());//""
console.log(Number(""));  //0

但是: console.log([[1]] == false); 结果为false

console.log([[1]].valueOf()); //[Array(1)]
console.log([[1]].toString());//"1"
console.log(Number("1"));  //1

eg5:console.log({} == {}); 结果为? false

分析:类型, 值相同时,比较堆/栈内存中的地址是否相同每一个对象在 堆内存中地址都是不一样的,除非是同一个对象,{},{}

形式上看着是一样的,但其实是两个不同堆地址的内存空间。所以为false

eg6: console.log([] == []); 结果为? false

分析:类型, 值相同时,比较堆/栈内存中的地址是否相同

两个都是[]数组对象,但是在堆内存中地址不同,所以为false

eg7:为什么 null > 0 结果为false,null >= false结果为true,null == false,结果为false?

易错:易错认为 null == 0 结果为 true

console.log(null > 0);  //false
console.log(null >= 0); //true
console.log(null == 0); //false

console.log(Number(null));  // 0

结果分析:

> / <  :对比大于或小于的时候, null 会尝试转型为number 型数据, 转化之后null为0, 0>0是错误的,所以结果为 false. 

>= / <= :同上,对比 大于等于 或 小于等于 的时候, 会先判断大于或小于, 这时候null 会尝试转型为number , 转化之后null为0, 0>0是错误的,但是0=0是正确的, 这是 “或” 的判断, 所以结果为 true

== :null在设计上,对比等于的时候不尝试转型. null和0不转型的话,是不会相等的, 所以null == 0结果为false.

 9.常见的 "==" 关系表

一道阿里面试题:JavaScript中如果判断两个变量相等?

满分回答思路:01.使用绝对相等 "==="判断,并说明:NaN与NaN,+0和-0除外

                         02.或者使用ES6中object.is()方法判断,并说明与"==="相等的区别

                         03.了解object.is()是如何实现的?

                        后面学习完ES6再回来看。。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值