乐趣区

关于javascript:JavaScript面试题大坑之隐式类型转换实例代码

1. 电脑系统 windows10 专业版
2. 隐式转换介绍

在 js 中,当运算符在运算时,如果两边数据不对立,CPU 就无奈计算,这时咱们编译器会主动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算

这种无需程序员手动转换,而由编译器主动转换的形式就称为隐式转换

例如 1 >“0”这行代码在 js 中并不会报错,编译器在运算符时会先把左边的”0”转成数字 0‘而后在比拟大小, 输入后果为 true 

2-1. 隐式转换规则

1. 转成 string 类型:+(字符串连接符)2.. 转成 number 类型:++/–(自增自减运算符) + - * / %(算术运算符) > < >= <= == != === !=== (关系运算符)

 转成 boolean 类型:!(逻辑非运算符)

2.3- 坑一:字符串连接符与算术运算符隐式转换规则混同

常见面试题如下
 console.log (1 + "true");//‘1true‘'
 console.log (1 + true);//2
 console.log (1 + undefined);// NaN
 console.log (1 + null);//1
原理剖析
/* 此类问题的坑:将字符串连接符 (+ : 只有 + 号两边有一边是字符串) 与算术运算符 (+: 两边都是数字) 的隐式转换搞混同
 1. 字符串连接符 +:会把其余数据类型调用 String()办法转成字符串而后拼接
 2. 算术运算符 +:会把其余数据类型调用 Number()办法转成数字而后做加法计算
 */
 //+ 是字符串连接符:String(1) + 'true' = '1true' console.log (1 + "true");//1true
 //+ 是算术运算符:1 + Number(true) = 1 + 1 = 2 console.log (1 + true);//2
 // + 是算术运算符:1 + Number(undefined) = 1 + NaN = NaN console.log (1 + undefined);// NaN
 // + 是算术运算符:1 + Number(null) = 1 + 0 = 1 console.log (1 + null);//1

2.4- 坑二:关系运算符:会把其余数据类型转换成 number 之后再比拟关系

常见面试题如下
console.log ("2" > 10);//false console.log ("2" > "10");//true console.log ("abc" > "b");//false console.log ("abc" > "aad");//true console.log (NaN == NaN);//false console.log (undefined == null);//true
原理剖析
//2.1 : 当关系运算符两边有一边是字符串的时候,会将其余数据类型应用 Number()转换,而后比拟关系
 console.log ("2" > 10);//false Number('2') > 10 =   2 > 10   =  false
 /*2.2:当关系运算符两边都是字符串的时候,此时同时转成 number 而后比拟关系
 重点:此时并不是依照 Number()的模式转成数字,而是依照字符串对应的 unicode 编码来转成数字
 应用这个办法能够查看字符的 unicode 编码:字符串.charCodeAt(字符下标,默认为 0)  字符串 "0".charCodeAt() 为 48。字符串 a.charCodeAt() 为 97, 字符串 z.charCodeAt() 为 122。*/
 console.log ("2" > "10");//true  '2'.charCodeAt() > '10'.charCodeAt() = 50 > 49 = true
 console.log ("2".charCodeAt () );// 数字 50
 console.log ("10".charCodeAt () );// 数字 49(默认返回第一个字符的编码,如果想要查问第二个字符能够传参下标)// 多个字符从左往右顺次比拟 console.log ("abc" > "b");//false  先比拟 'a' 和 'b','a' 与 'b' 不等,则间接得出后果
 console.log ("abc" > "aad");//true  先比拟 'a' 和 'a',两者相等,持续比拟第二个字符 'b' 与 'a' , 得出后果
 console.log ("a".charCodeAt () );// 数字 97
 console.log ("b".charCodeAt () );// 数字 98
 //2.3 非凡状况(忽视规定):如果数据类型是 undefined 与 null,,得出固定的后果 console.log (undefined == undefined);//true
 console.log (undefined == null);//true
 console.log (null == null);//true
 //2.4 非凡状况(忽视规定):NaN 与任何数据比拟都是 NaN console.log (NaN == NaN);//false

2.5- 坑三:简单数据类型在隐式转换时会先转成 String,而后再转成 Number 运算

原理剖析
/* 简单数据类型转 number 程序如下
 1. 先应用 valueOf()办法获取其原始值,如果原始值不是 number 类型,则应用 toString()办法转成 string
 2. 再将 string 转成 number 运算
 */
 console.log ([ 1,2] == '1,2' );//true  先将右边数组转成 string,而后左边也是 string 则转成 unicode 编码运算
 console.log ([ 1, 2].valueOf ());// [1,2]
 console.log ([ 1, 2].toString ());// '1,2'
 var a = {};
 console.log (a == "[object Object]" );//true
 console.log (a.valueOf ().toString());//[object Object] /* 剖析:逻辑与运算一假则假,要想 if 分支语句小括号条件成立,则必须要让 a 的值同时等于 1 且 等于 2 且等于 3
 乍看之下,如同基本不可能实现,然而简单数据类型会先调用 valueOf()办法, 而后转成 number 运算
 而对象的 valueOf()办法是能够重写的
 */
 var a = {
  i : 0,// 申明一个属性 i
  valueOf:function ( ) {return ++a.i;// 每调用一次,让对象 a 的 i 属性自增一次并且返回}
 }
 if (a == 1 && a == 2 && a == 3){// 每一次运算时都会调用一次 a 的 valueOf()办法
  console.log ("1");
 }

2.6- 坑四:逻辑非隐式转换与关系运算符隐式转换搞混同

请留神~
空数组的 toString()办法会失去空字符串,而空对象的 toString()办法会失去字符串[object Object](留神第一个小写 o,第二个大写 O 哟)
常见面试题如下
// 大坑 
console.log ([] == 0 );//true 
console.log (! [] == 0 );//true
// 神坑
console.log ([] == ! []);//true
console.log ([] == []);//false 
// 史诗级坑
console.log({} == !{});//false 
console.log({} == {});//false
原理剖析
/*1. 关系运算符:将其余数据类型转成数字
2. 逻辑非:将其余数据类型应用 Boolean()转成布尔类型
  * 以下八种状况转换为布尔类型会失去 false
   * 0、-0、NaN、undefined、null、''(空字符串)、false、document.all()
  * 除以上八种状况之外所有数据都会失去 true
 */
 /* 原理(1)[].valueOf().toString() 失去空字符串(2)Number('') == 0 成立
 */
 console.log ([] == 0 );//true
 /* 原理 : 实质是 `![]` 逻辑非表达式后果 与 0 比拟关系
  (1)逻辑非优先级高于关系运算符 ![] = false (空数组转布尔失去 true,而后取反失去 false)
  (2)false == 0 成立
 */
 console.log (! [] == 0 );//true 
/* 原理:实质其实是 ` 空对象{}` 与 `!{}` 这个逻辑非表达式后果做比拟(1){}.valueOf().toString() 失去字符串 '[object Object]'
  (2) !{} = false
  (3) Number('[object Object]') == Number(false)
 */
 console.log({} == !{});//false
 // 援用类型数据存在堆中,栈中存储的是地址,所以他们的后果是 false console.log({} == {});//false
 /* 原理:实质是 ` 空数组[]` 与 `![]` 这个逻辑非表达式后果做比拟
 (1) [].valueOf().toString() 失去空字符串 ''
 (2) ![] = false
 (3) Number('') == Number(false) 成立 都是 0
 */
 console.log ([] == ! []);//true
 // 援用类型数据存在堆中,栈中存储的是地址,所以他们的后果是 false console.log ([] == []);//false 
 console.log ({}.valueOf ().toString () )//[object Object]
 console.log ([].valueOf ().toString () );//'' 空字符串

3. 本期的分享到了这里就完结啦, 心愿对你有所帮忙, 让咱们一起致力走向巅峰!

退出移动版