🚀看代码写输出——隐式类型转换(附例题)

180 阅读5分钟

image.png

前言

我们面试过程中,也时不时会碰到这类题型——看代码写输出,很多基础不牢的小伙伴就在这类题目中翻了大跟斗,所以笔者也想尝试写一下这类题目的分享,也顺便帮自己巩固这类的知识~

数学运算符中的类型转换

规则一我们在对各种非Number类型运用数学运算符(- * / > <)时,会先将非Number类型转换为Number类型。

那么各类非Number类型转换成Number类型有哪些结果呢?

Number的强类型转换

// 数值:转换后还是原来的值
Number(123) // 123

// 字符串:如果可以被解析为数值,则转换为相应的数值
Number('123') // 123

// 字符串:如果不可以被解析为数值,返回 NaN
Number('123abc') // NaN

// 空字符串转为0
Number('') // 0

// 布尔值:true 转成 1,false 转成 0
Number(true) // 1
Number(false) // 0

// null:转成0
Number(null) // 0

// undefined:转成 NaN
Number(undefined) // NaN

OK,此时你已经会了一类题目了

1 - true // 0, 首先把 true 转换为数字 1, 然后执行 1 - 1
1 - null // 1,  首先把 null 转换为数字 0, 然后执行 1 - 0

const a = '123';
const b = 123;

console.log(1 < 2 < 3); // 先比较 1 < 2 返回true,变成了比较 true < 3,应用规则一,将true转换成数字1,最后判断 1 < 3 ,毫无疑问返回true    
console.log(3 > 2 > 1); // 先比较 3 > 2 返回false,变成了比较 false > 3, 应用规则一,将false转换成数字0,最后判断 1 > 3,这肯定就是返回false

加法的特殊情况

为什么加法要区别对待?

因为JS里 +还可以用来拼接字符串。

谨记以下3条:

  • 当一侧为String类型,被识别为字符串拼接,并会优先将另一侧转换为字符串类型。
  • 当一侧为Number类型,另一侧为原始类型,则将原始类型转换为Number类型。
  • 当一侧为Number类型,另一侧为引用类型,将引用类型和Number类型转换成字符串后拼接。

注意以上 3 点,优先级从高到低

123 + '123' // 123123   (规则1)
123 + null  // 123    (规则2)
123 + true // 124    (规则2)
123 + {}  // 123[object Object]    (规则3)

现在这种题在面试中就是送分题了,这也丢了就说不过去了吧~

逻辑语句中的类型转换

单个变量

如果只有单个变量,会先将变量转换为Boolean值。

只有 null undefined '' NaN 0 false 这几个是 false,其他的情况都是 true,比如 {} , []

== 比较中的五条规则

规则1

  • 规则 1:NaN和其他任何类型比较永远返回false(包括和他自己)。
    NaN == NaN // false
    

规则2

  • 规则 2:Boolean 和其他任何类型比较,Boolean 首先被转换为 Number 类型。
    true == 1  // true 
    true == '2'  // false, 先把 true 变成 1,而不是把 '2' 变成 true
    undefined == false // false ,首先 false 变成 0,然后参考规则4
    null == false // false,同上
    

规则3

  • 规则 3:StringNumber比较,先将String转换为Number类型。
    123 == '123' // true, '123' 会先变成 123
    '' == 0 // true, '' 会首先变成 0
    

规则4

  • 规则 4:null == undefined比较结果是true,除此之外,nullundefined和其他任何结果的比较值都为false

    null == undefined // true
    null == '' // false
    null == 0 // false
    null == false // false
    undefined == '' // false
    undefined == 0 // false
    undefined == false // false
    

规则5

  • 规则 5:原始类型引用类型做比较时,引用类型会依照ToPrimitive规则转换为原始类型。

    ToPrimitive规则:它遵循先valueOftoString的模式期望得到一个原始类型。如果还是没法得到一个原始类型,就会抛出 TypeError

有些小伙伴可能对valueoftoString方法还不太了解,这里介绍一下

valueof

valueOf 方法将对象转换为一个原始值

// Array:返回数组对象本身
var array = ["ABC", true, 12, -5];
console.log(array.valueOf() === array);   // true

// Date:当前时间距1970年1月1日午夜的毫秒数
// Sun Aug 18 2013 23:11:59 GMT+0800 (中国标准时间)
var date = new Date(2013, 7, 18, 23, 11, 59, 230); 
console.log(date.valueOf());   // 1376838719230

// Number:返回数字值
var num =  15.26540; // 15.2654
num.valueOf() // 15.2654
console.log(num.valueOf() === num);   // true

// 布尔:返回布尔值true或false
var bool = true;
console.log(bool.valueOf() === bool);   // true

// new一个Boolean对象
var newBool = new Boolean(true); // Boolean {true}
newBool.valueOf() // true


// Function:返回函数本身
function foo(){}
console.log( foo.valueOf() === foo );   // true


// Object:返回对象本身
var obj = {name: "张三", age: 18};
console.log( obj.valueOf() === obj );   // true

// String:返回字符串值
var str = "http://www.xyz.com";
console.log( str.valueOf() === str );   // true


toSring

toString()  方法返回一个表示该对象的字符串

// Number:返回字符串
var n = 33;
console.log(n.toString());//'33'

// Array:返回数组内容组成的字符串
var a = [1,2,3,4];
console.log(a.toString());//"1,2,3,4"

// Function:返回函数代码字符串
var a = function(){};
console.log(a.toString());//"function(){};"

// 正则RegExp类型:返回原正则表达式
var a = /a/g;
console.log(a.toString());///"a/g"

// Date类型:返回表示当前时间的字符串
 var obj = new Date();
 console.log(obj);//Wed May 10 2017 18:20:05 GMT+0800 (中国标准时间)
 console.log(typeof obj);//object
 console.log(obj.toString());//"Wed May 10 2017 18:20:05 GMT+0800 (中国标准时间)"


//对象Object类型及自定义对象类型:返回 [object Object]

 var obj = {a:1};
 console.log(obj.toString());//"[object Object]"

 function Foo(){};
 var foo = new Foo();
 console.log(foo.toString());//"[object Object]"

例题

那么再上几个例题感受一下吧~

1. [] == ![]

	- 第一步,根据逻辑语句中单个变量规则![] 会变成 false
	- 第二步,应用 规则2 ,题目变成: [] == 0
	- 第三步,应用 规则5 ,[]的valueOf是0,题目变成: 0 == 0
	- 所以, 答案是 true !

2. 拆解 {} == !{}

    - 第一步,根据逻辑语句中单个变量规则!{} 会变成 false
    - 第二步,应用 规则2 ,题目变成: {} == 0
    - 第三步,应用 规则5 ,{}的valueOf是{},进行toString操作,{}的toString变成"[object Object]"
    题目变成:"[object Object]" == 0
    - 第四步,应用 规则3,将字符串变成数字类型"[object Object]"变成NaN,题目变成NaN == 0
    - 第五步,应用规则一, 返回false
        

小结

其实大部分的面试题掌握了上述的规则,问题都不大的。

当然这里我给的例题肯定还是不够的,也需要友友们结合网上一些其他的面经,再结合上述的规则,把它们用熟,这一块肯定就没大问题了~

本文正在参加「金石计划」