JavaScript面试题,为什么[] + 0 = '0', 而{} + 0 = 0?
介绍
昨天在网上看到一道面试题,是关于JavaScript中的+元算符的,如下:
[] + 0 = ?
{} + 0 = ?
要解决这道题,我们首先要了解JavaScript中+运算符的行为,+元算符在JavaScript中主要有三种用途:一是用于数字相加,二是用于字符串连接,三是用于类型转换。
1 + 2 = 3 // 数字相加
'Hello, ' + 'World!' = 'Hello, World!' // 字符串连接
+'1' = 1 // 字符串转换为数字
再回到面试题,可以看出,这并非常规的加法操作,因为运算符两侧的操作数并非都是数字类型,而是包含了数组和对象。难道是字符串连接吗?不确定,是类型转换?好像也不是。
追本溯源,我们先看看MDN上关于+的运行规则吧:
如果+元算符的操作数包含非基本类型(比如对象,数组等),先将其转换为基本类型(primitive type)。
在JavaScript中,基本类型包括
undefined、null、boolean、number、string、BigInt、Symbol。
当+元算符两侧都是基本类型时,执行规则如下:
- 有一个操作数是字符串时,将另一个操作数也转换为字符串,并执行字符串连接;
- 有一个操作数是
BigInt时,将另一个操作数也转换为BigInt,并执行加法; - 否则,将两个操作数都转换为数字,并执行加法。
举几个列子:
1 + `2` = '12' // 满足规则1,将数字1转换为字符串'1',执行字符串连接
1 + 2n = 3n // 满足规则2,将数字1转换为
null + true = 1 // 满足规则3,将null转换为数字0,将true转换为数字1,执行加法
我们这道题不涉及BigInt,所以只需要关注字符串连接和数字加法就好。
现在来看[] + 0该如何执行,首先[]是数组,不属于基本类型,所以先将它转换为基本类型,对象类型转换为基本类型的操作如下:
- 调用对象的
toPrimitive方法; - 如果没有
toPrimitive方法,则调用valueOf方法; - 如果
valueOf方法返回的值不是基本类型,则调用toString方法; - 如果
toString方法返回的值仍不是基本类型,则抛出错误。
所以[] + 0的执行过程如下:
[]没有toPrimitive方法,所以调用valueOf方法。valueOf方法返回值仍然是数组对象[]。- 接着调用
toString方法,返回空字符串''。
因此,[] + 0等价于'' + 0, 此时+两侧都是基本类型了,并且满足有一侧是字符串的条件,所以将另一侧的操作数0也转换为字符串,执行字符串连接,结果为'' + '0' = '0'。
再来看{} + 0, {}和[]一样,都是对象类型,所以先将其转换为基本类型。
{}没有toPrimitive方法,所以调用valueOf方法,返回值仍然是对象{}。- 接着调用
toString方法,返回字符串'[object Object]' - 然后将
'[object Object]'与0进行字符串连接,结果为'[object Object]' + '0'='[object Object]0'。
哈哈,但是我要告诉你,这个答案是错误的,这个分析是没有问题的,但是JavaScript解释器不同意,当它看到{}时,会将其解释为一个空的代码块,而不是一个空对象,因此,{} + 实际上等于下面的代码:
{}
+ 0
这时,而{}被视为一个空代码块, 没有返回任何结果,而+ 0被解释为一条独立的语句,返回值是0,最终结果是0。
如果要让代码按照我们上面分析的过程执行,那么就要防止JavaScript将{}解释为空代码块,可以用()将其包裹起来。
({}) + 0 // 结果为 '[object Object]0'
总结
[] + 0 = '0'
{} + 0 = 0
说实话这道题目比较偏门,但是对于了解JavaScript中+运算符的行为还是很有帮助的,通过一道题,能了解一个知识点,还是很值得的。
有的时候,不要光纠结问题的答案,更应该关注的是问题背后的原理的规则,就比如这道题,在没有写这篇文章之前,如果让我回答,我是答不上来的,我需要查阅资料,了解+运算符的行为规则,才能得出正确的答案。我觉得相比知道答案,更有意思的是分析的过程,这个过程体现了一个程序员处理问题的逻辑思维能力,小到一道面试题,大到一个复杂的系统设计,都是如此。那么如何培养这种能力呢,我也一直在寻找答案...
今天就到这里了,我们明天见。
今天周六,准备出去逛逛,奈何天气太热,动也不想动,只能呆在家里了。锁凤十代打了两天,手感非常不错,准备留下了,之前买的猛禽就退了吧,现在赚钱不易,还是要精打细算的好。
JavaScript面试题,为什么[] + 0 = '0', 而{} + 0 = 0?的更多相关文章
- 如何解决JavaScript中0.1+0.2不等于0.3
console.log(0.1+0.2===0.3)// true or false?? 在正常的数学逻辑思维中,0.1+0.2=0.3这个逻辑是正确的,但是在JavaScript中0.1+0.2!= ...
- 百度地图-省市县联动加载地图 分类: Demo JavaScript 2015-04-26 13:08 530人阅读 评论(0) 收藏
在平常项目中,我们会遇到这样的业务场景: 客户希望把自己的门店绘制在百度地图上,通过省.市.区的选择,然后加载不同区域下的店铺位置. 先看看效果图吧: 实现思路: 第一步:整理行政区域表: 要实现通过 ...
- 深入理解JavaScript系列:为什么03-0.2不等于0.1
五一宅家看书,所以接着更新一篇文章. 今天讲一下为什么03-0.2不等于0.1这个问题. 有点标题党的味道,在JavaScript中,当你试着对小数进行加减运算时,有时候会发现某个结果并非我们所想的那 ...
- jQuery easyUI datagrid 增加求和统计行 分类: JavaScript 2015-01-14 17:46 2178人阅读 评论(0) 收藏
在datagrid的onLoadSuccess事件增加代码处理. <style type="text/css"> .subtotal { font-weight: bo ...
- null的坑 和 比较运算符、相等运算符的隐式转换问题 (在javascript中,null>=0 为真,null<=0 为真,null==0却为假,null到底是什么?)
null在关系运算中的坑 & 关系运算符的隐式转换问题 注意: 比较运算符 和 相等运算符 的 ECMAscript 语法实现不同. 比较运算符 和 相等运算符 对数据进行了隐式转换, 相当于 ...
- 为什么在JavaScript中0.1+0.2不等于0.3?
0.1+0.2不等于0.3?是不是有点颠覆你的认知,但是,在js中,是真实存在的! console.log(0.1+0.2); // 0.30000000000000004 其实这都是因为浮点数运算的 ...
- 为什么js中0.1+0.2不等于0.3,怎样处理使之相等?(转载)
为什么js中0.1+0.2不等于0.3,怎样处理使之相等? console.log(0.1+0.2===0.3)// true or false?? 在正常的数学逻辑思维中,0.1+0.2=0.3这个 ...
- js正则表达式校验非负浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Zepto,Zepto API 中文版,Zepto 中文手册,Zepto API,Zepto API 中文版,Zepto 中文手册,Zepto API 1.0, Zepto API 1.0 中文版,Zepto 1.0 中文手册,Zepto 1.0 API-translate by yaotaiyang
Zepto,Zepto API 中文版,Zepto 中文手册,Zepto API,Zepto API 中文版,Zepto 中文手册,Zepto API 1.0, Zepto API 1.0 中文版,Z ...
- paip.jdk1.4 1.5(5.0) 1.6(6.0) 7.0 8.0特点比较与不同
paip.jdk1.4 1.5(5.0) 1.6(6.0) 7.0 8.0特点比较与不同 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地 ...
随机推荐
- JAVA基础之多线程一期
一.并发与并行的区别 并发:指同一时间段,两个或多个事件交替进行 并行:指同一时间段,两个或多个事件同时进行 二.进程与线程的区别 进程:正在内存中运行的程序就是进程 线程:线程归属于进程,它是进程中 ...
- 一文搞懂Dockerfile
Dockerfile官网 https://docs.docker.com/reference/dockerfile/ 什么是Dockerfile? Dockerfile 是一个文本文件,其内包含了一条 ...
- 雷总小米十周年演讲---国外友人评价第一次看到MIUI系统
雷总在小米十周年演讲时提到的当时讨论MIUI系统的帖子 xdadevelopers论坛 https://forum.xda-developers.com/showthread.php?t=787877 ...
- TVM:Schedule的理解
schedule与计算逻辑分离是自动代码生成技术的核心概念,由MIT CASIL组的Jonathan Ragan-Kelley在2012年发表在SIGGRAPH上的文章率先提出,然后在2013年发表在 ...
- 一个低PE的股票池--选股策略
EP因子即市盈率因子,常被投资者使用的几个估值因子之一.一般使用PE,即Price to Earning,维基百科上的解释:市盈率指每股市价除以每股收益盈利(Earning Per Share,EPS ...
- JVM 使用jstat分析系统的垃圾回收情况
jstat -gcutil 输出结果分析_助你了解jvm命令,查找JVM堆栈信息,分析性能问题.下面介绍一下jstat命令: jstat:虚拟机统计信息监视工具(JVM Statistics Moni ...
- AI面试助手“面试精灵”发布新功能——AI笔试助手
引言 在职场竞争日益激烈的今天,面试已成为决定职业发展的关键一步.许多专业人士虽然在专业领域拥有深厚的知识,却可能缺乏面试技巧.为了帮助这些专业人士更轻松地获得理想的工作,我们推出了革命性的AI面试助 ...
- Linux下搭建Kafka集群
摘要 Kafka 是一个分布式的基于push-subscribe的消息系统,它具备快速.可扩展.可持久化的特点.由 LinkedIn 开源,用作 LinkedIn 的活动流(Activity Stre ...
- 通过chrome插件自动生成博客评论,高效发外链
最近crazy cattle 3d这个词爆火,很多人都在做,竞争异常激烈,甚至可以说是惨不忍睹. 从最近的数据看,胜出的主要是crazycattle3d.com, crazycattle3d.io, ...
- python C3算法
Python MRO C3算法是python当中计算类继承顺序的一个算法,从python2.3以后就一直使用此算法了. c3 linearization算法称为c3线性化算法 C3算法原理 首先定义几 ...