JS面试题大坑之隐式类型转换实例代码


Posted in Javascript onOctober 14, 2018

1.1-隐式转换介绍

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

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

例如1 > "0"这行代码在js中并不会报错,编译器在运算符时会先把右边的"0"转成数字0`然后在比较大小

1.2-隐式转换规则

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

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

1.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

1.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)
 */
 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

1.5-坑三:复杂数据类型在隐式转换时会先转成String,然后再转成Number运算

• 原理分析

JS面试题大坑之隐式类型转换实例代码

JS面试题大坑之隐式类型转换实例代码

/*复杂数据类型转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" );
 }

1.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 () );//'' 空字符串

JS面试题大坑之隐式类型转换实例代码

JS面试题大坑之隐式类型转换实例代码

JS面试题大坑之隐式类型转换实例代码

总结

以上所述是小编给大家介绍的JS面试题大坑之隐式类型转换实例代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
javascript 控制弹出窗口
Apr 10 Javascript
js弹出框轻量级插件jquery.boxy使用介绍
Jan 15 Javascript
jQuery 插件仿百度搜索框智能提示(带Value值)
Jan 22 Javascript
Jquery attr()方法 属性赋值和属性获取详解
Apr 15 Javascript
JS实现留言板功能
Jun 17 Javascript
Vue组件的使用教程详解
Jan 05 Javascript
使用mint-ui实现省市区三级联动效果的示例代码
Feb 09 Javascript
vue.js-div滚动条隐藏但有滚动效果的实现方法
Mar 03 Javascript
Vue中 v-if 和v-else-if页面加载出现闪现的问题及解决方法
Oct 12 Javascript
jQuery实现动态生成年月日级联下拉列表示例
May 11 jQuery
javascript实现用户必须勾选协议实例讲解
Mar 24 Javascript
JavaScript高级程序设计之基本引用类型
Nov 17 Javascript
JS中appendChild追加子节点无效的解决方法
Oct 14 #Javascript
详解ES6 Symbol 的用途
Oct 14 #Javascript
javascript实现文本框标签验证的实例代码
Oct 14 #Javascript
Vue+webpack项目配置便于维护的目录结构教程详解
Oct 14 #Javascript
单页面vue引入百度统计的使用方法示例详解
Oct 13 #Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 #Javascript
详解webpack loader和plugin编写
Oct 12 #Javascript
You might like
六酷社区论坛HOME页清新格调免费版 下载
2007/03/07 PHP
PHP的基本常识小结
2013/07/05 PHP
thinkphp备份数据库的方法分享
2015/01/04 PHP
YII Framework框架教程之国际化实现方法
2016/03/14 PHP
yii2.0实现pathinfo的形式访问的配置方法
2016/04/06 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
学习ExtJS TextField常用方法
2009/10/07 Javascript
extjs 04_grid 单击事件新发现
2012/11/27 Javascript
JavaScript中用字面量创建对象介绍
2014/12/31 Javascript
Javascript中的apply()方法浅析
2015/03/15 Javascript
jqueryMobile使用示例分享
2016/01/12 Javascript
js删除数组元素、清空数组的简单方法(必看)
2016/07/27 Javascript
jQuery实现选中行变色效果(实例讲解)
2017/07/06 jQuery
浅谈ES6新增的数组方法和对象
2017/08/08 Javascript
Node.js学习之查询字符串解析querystring详解
2017/09/28 Javascript
用React实现一个完整的TodoList的示例代码
2017/10/30 Javascript
微信小程序实现折叠展开效果
2018/07/19 Javascript
vue中接口域名配置为全局变量的实现方法
2018/09/20 Javascript
vue2.0 解决抽取公用js的问题
2020/07/31 Javascript
[00:36]DOTA2上海特级锦标赛 Archon战队宣传片
2016/03/04 DOTA
PyQt5每天必学之日历控件QCalendarWidget
2018/04/19 Python
对Python3.6 IDLE常用快捷键介绍
2018/07/16 Python
Python字典的基本用法实例分析【创建、增加、获取、修改、删除】
2019/03/05 Python
python requests模拟登陆github的实现方法
2019/12/26 Python
python实现引用其他路径包里面的模块
2020/03/09 Python
Python3 ID3决策树判断申请贷款是否成功的实现代码
2020/05/21 Python
美国在线乐器和设备商店:Musician’s Friend
2018/07/06 全球购物
求最大连续递增数字串(如"ads3sl456789DF3456ld345AA"中的"456789")
2015/09/11 面试题
成都思必达公司C#程序员招聘面试题
2013/06/26 面试题
公司企业表扬信
2014/01/11 职场文书
个人简历自我评价怎么写
2015/03/10 职场文书
党小组推荐意见
2015/06/02 职场文书
2016年小学感恩节活动总结
2016/04/01 职场文书
创业计划书之香辣虾火锅
2019/09/23 职场文书
goland 恢复已更改文件的操作
2021/04/28 Golang
Java Redisson多策略注解限流
2022/09/23 Java/Android