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 相关文章推荐
修复IE9&amp;safari 的sort方法
Oct 21 Javascript
Jquery中删除元素的实现代码
Dec 29 Javascript
判断多个input type=file是否有已经选择好文件的代码
May 23 Javascript
jQuery操作 input type=checkbox的实现代码
Jun 14 Javascript
在JavaScript的jQuery库中操作AJAX的方法讲解
Aug 15 Javascript
jQuery+HTML5美女瀑布流布局实现方法
Sep 21 Javascript
学习使用bootstrap3栅格系统
Apr 12 Javascript
原生javascript实现分页效果
Apr 21 Javascript
Angular中自定义Debounce Click指令防止重复点击
Jul 26 Javascript
angularjs实现猜数字大小功能
May 20 Javascript
尝试自己动手用react来写一个分页组件(小结)
Feb 09 Javascript
thinkjs微信中控之微信鉴权登陆的实现代码
Aug 08 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
php中怎么搜索相关联数组键值及获取之
2013/10/17 PHP
ThinkPHP标签制作教程
2014/07/10 PHP
用 Composer构建自己的 PHP 框架之构建路由
2014/10/30 PHP
PHP的Yii框架中View视图的使用进阶
2016/03/29 PHP
PHP生成唯一ID之SnowFlake算法
2016/12/17 PHP
PHP利用curl发送HTTP请求的实例代码
2020/07/09 PHP
fromCharCode和charCodeAt 方法
2006/12/27 Javascript
为jQuery增加join方法的实现代码
2010/11/28 Javascript
JQuery自适应IFrame高度(支持嵌套 兼容IE,ff,safafi,chrome)
2011/03/28 Javascript
jQuery UI 实现email输入提示实例
2013/08/15 Javascript
小米公司JavaScript面试题
2014/12/29 Javascript
基于JavaScript实现移动端点击图片查看大图点击大图隐藏
2015/11/04 Javascript
JavaScript实现显示函数调用堆栈的方法
2016/04/21 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
2016/07/25 Javascript
jquery实现拖动效果
2016/08/10 Javascript
jQuery视差滚动效果网页实现方法经验总结
2016/09/29 Javascript
JavaScript实现点击按钮复制指定区域文本(推荐)
2016/11/25 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
2017/03/30 Javascript
详解如何使用babel进行es6文件的编译
2018/05/29 Javascript
vue router 跳转后回到顶部的实例
2018/08/31 Javascript
webpack 静态资源集中输出的方法示例
2018/11/09 Javascript
VUE 组件转换为微信小程序组件的方法
2019/11/06 Javascript
[02:38]DOTA2超级联赛专访Loda 认为IG世界最强
2013/05/27 DOTA
Python网络编程 Python套接字编程
2017/09/13 Python
Selenium定位元素操作示例
2018/08/10 Python
python构建指数平滑预测模型示例
2019/11/21 Python
python实现从wind导入数据
2019/12/03 Python
Sunglasses Shop德国站:欧洲排名第一的太阳镜网站
2017/08/01 全球购物
美国最大的旗帜经销商:Carrot-Top
2018/02/26 全球购物
意大利在线药房:Saninforma
2021/02/11 全球购物
说说在weblogic中开发消息Bean时的persistent与non-persisten的差别
2013/04/07 面试题
学生自我评价范文
2014/02/02 职场文书
大专毕业生求职信
2014/07/05 职场文书
2015年预防青少年违法犯罪工作总结
2015/05/22 职场文书
Oracle11g r2 卸载干净重装的详细教程(亲测有效已重装过)
2021/06/04 Oracle
Python 装饰器(decorator)常用的创建方式及解析
2022/04/24 Python