以下内容均为个人整理的观点,一个个字码出来的,不喜勿喷
我们先做一道面试题吧
console.log('[]==![]');
请想出你的答案,并说服你自己吧。
然后你再做一道吧:
console.log('{}==!{}');
我们再做一道面试题吧
console.log([1,2,3] == '1,2,3')
自己尝试一下,做对了吗?
其实这三道题牵扯到了两个知识点,一个是类型的转换和比较运算符,今天重点说类型的转换。
答案及解析见文末~~~
-
转换成Number类型的规则
//如果转换的是数字,那么结果不变 console.log(Number(2));//2 //如果转换的是字符串,但是是纯数值,那么结果是数字 console.log(Number('-23'));//-23 //如果转换的是字符串,但是是包含非数字内容,那么结果是NaN console.log(Number('abx11'));//NaN //如果转换的是字符串,但是是包含非数字内容,那么结果是NaN console.log(Number('11abx'));//NaN //如果转换的是null,结果是0 console.log(Number(null));//0 //如果转换的是undefined,那么结果是NaN console.log(Number(undefined));//NaN //如果转换的是布尔值true,那么结果是1 console.log(Number(true));//1 //如果转换的是布尔值false,那么结果是0 console.log(Number(false));//0 //如果转换的是空数组,那么结果是0 console.log(Number([]));//0 //如果转换的是非空数组,那么结果是NaN console.log(Number(["2","3"]));//NaN //如果转换的是对象(无论是否是空的),那么结果是NaN console.log(Number({}));//NaN
当然将其他类型转换成number类型的还有parseInt和parseFloat,但是今天讨论的是转化规则,对其他的不做详谈。
-
转化成String类型的规则
//如果转换的是数字,那么结果是字符串的数值 console.log(String(3))//'3' //如果转换的是字符串,那么结果还是原字符串 console.log(String('abc'))//'abc' //如果转换的是null,那么结果是字符串‘null’ console.log(String(null))//'null' //如果转换的是undefined,那么结果是字符串'undefined' console.log(String(undefined))//'undefined' //如果转换的是布尔值true,那么结果是字符串'true' console.log(String(true))//'true' //如果转换的是布尔值false,那么结果是字符串'false' console.log(String(false))//'false' //如果转换的是空对象,那么结果是字符串'[object Object]' console.log(String({}))//'[object Object]' //如果转换的是非空对象,那么结果仍是字符串'[object Object]' console.log(String({name:"lily"}))//'[object Object]' //如果转换的是空数组,那么结果是空字符串 console.log(String([]))//空字符串 //如果转换的是非空数组,那么结果是字符串'2,3'(数组的值包含逗号都在字符串中) console.log(String([2,3]))//'2,3'
当然还有toString等方法也可以将其他类型转化成字符串,这个文章不做详细讨论
-
转换成Boolean类型的规则
//如果转换的是数字0,那么结果false console.log(Boolean(0))//false //如果转换的是数字非0,那么结果true console.log(Boolean(-1))//true //如果转换的是数字非0,那么结果true console.log(Boolean(3))//true //如果转换的是空字符串,那么结果false console.log(Boolean(""))//false //如果转换的是数字非空字符串,那么结果true console.log(Boolean("abc"))//true //如果转换的是null,那么结果false console.log(Boolean(null))//false //如果转换的是undefined,那么结果false console.log(Boolean(undefined))//false //如果转换的是布尔值true,那么结果仍然是true console.log(Boolean(true))//true //如果转换的是布尔值false,那么结果仍然是false console.log(Boolean(false))//false //如果转换的是空对象,那么结果是true console.log(Boolean({}))//true //如果转换的是非空对象,那么结果仍然是true console.log(Boolean({name:"lily"}))//true //如果转换的是空数组,那么结果仍然是true console.log(Boolean([]))//true //如果转换的是非空数组,那么结果仍然是true console.log(Boolean([3,4]))//true
好了,知道上边的规则之后,我们来说一下刚才的3道题了
console.log('[]==![]'); console.log('{}==!{}'); console.log([1,2,3] == '1,2,3')
咦,我虽然知道了转换规则,但是好像缺了点什么?
那就是比较的时候怎么进行的转换的呢? (只讨论==的情况)
- 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1;
//先将true转化成数字1,然后比较相等,返回true console.log(true==1)//true
- 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值
//先将‘34’转换成数字34,然后比较返回true console.log("34"==34)//true
- 如果有一个操作数是NaN,则相等操作符返回 false ,而不相等操作符返回 true。重要提示:即使两个操作数都是NaN,相等操作符也返回 false了;因为按照规则, NaN 不等于 NaN
//首先将'abc'转换成NaN,NaN和任何相比都是false console.log("abc"==34);//false //NaN和NaN比也是false console.log(NaN==NaN)//false
- 两个等号判断等于的时候null 和undefined 是相等的
console.log(null==undefined);//true
- 如果两个操作数都是对象,则比较它们是不是同一个对象,如果两个操作数都指向同一个对象,则相等操作符返回 true;否则, 返回false
//只是两个空对象,但是分别是两个对象,所以不相等 console.log({}=={})//false var obj1 = {}; var obj2 = obj1; //obj1和obj2的地址都指向同一个对象,所以相等 console.log(obj2==obj1)//true
[] 和 {} 都是属于引用类型,引用类型是存放在栈内存中的,而在堆内存中会有一个或者多个地址来指向这个栈内存相对应的数据。所以在使用 == 操作符的时候,对于引用类型的数据,比较的是地址,而不是真实的值(会在引用类型值和基本类型值章节详细讲解)
终于能说这个面试题解析了
第一题:
[]==![]
- 首先!(非操作符)优先级高于==(等于操作符),所以先执行
![]
- 而空数组转化成布尔值是true,所以
![]
就是false
*然后开始比较,刚才说了 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值,所以==
之前空数组转化数字是0,==
之后false转换数字是0- 所以
[]==![]
为真(true)
第二题:
[]==![],和上一题道理一样,但是结果不一样
- 首先!(非操作符)优先级高于==(等于操作符),所以先执行
!{}
- 而空对象转化成布尔值是true,所以
![]
就是false
*然后开始比较,==
之前空对象转化数字是NaN,==
之后false转换数字是0,而NaN和任何值比较都是false- 所以
{}==!{}
为假(false)
第三题:
[1,2,3] == '1,2,3'
- 首先,一个值是字符串,另一个值是对象,所以将对象转化成字符串
- 而[1,2,3] 转换成字符串就是 '1,2,3'
- 所以
[1,2,3] == '1,2,3'
为真(true)
好了12点多了,今天就唠嗑到这里了,有疑问和建议可以留言,其他内容请期待以后的内容~
谢谢观看~