Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[] + {} 和 {} + []一样吗? #35

Open
fwon opened this issue Mar 1, 2017 · 1 comment
Open

[] + {} 和 {} + []一样吗? #35

fwon opened this issue Mar 1, 2017 · 1 comment

Comments

@fwon
Copy link
Owner

fwon commented Mar 1, 2017

这道题跟之前提到的[] == ![] 有异曲同工之妙,都是涉及到了隐式的强制类型转换。同样,我们直接开门见山,总结下加号操作符的运算规则。下面规则判断权重由上往下。

  1. 两个操作数都是数值 时,执行常规的数值加法计算。但有几个值的考虑
  • 如果有一个操作数是NaN, 则结果是NaN;
  • Infinity 加 Infinity 结果是 Infinity;
  • -Infinity 加 -Infinity 结果是 -Infinity;
  • Infinity 加 -Infinity 结果是NaN;
  • +0 加 +0 结果是+0;
  • -0 加 -0 结果是 -0;
  • +0 加 -0 结果是+0;
  1. 当有 一个操作数是字符串 时,应用如下规则:
  • 如果两个操作数都是字符串,则将两个字符串拼接起来;
  • 如果只有一个操作符是字符串,则两另一个操作符转换为字符串(toString),然后再将两个字符串拼接起来。

前面两条规则都非常简单,不会有混淆。对于其他情况,我总结了下面两条规则:

  1. 有一个操作数是复杂数据类型(对象,数组) 时,将两个操作数都转换为字符串(ToString)相加。
  2. 有一个操作数是简单数据类型(true/false, null,undefined) 时,同时不存在复杂数据类型和字符串,则将两个操作数都转换成数值(ToNumber)相加。
  3. 另外还有一种特殊情况{} + 头 的相加式,有些浏览器会将{}视为一个块符号,所以不会参与相加,而是把+符号视为转换符(Number)将后面的操作数转换为数值。

注意上面的规则的权重是从上到下的,每执行一步要从第一条规则开始再进行判断。

下面是改规则的一个判断流程图:

roadmap.path

我们来看看这几道题
1.[] + {}
根据规则,[] 和 {} 都是复杂数据类型,满足有一个操作符是复杂数据类型, 所以将两个值都转换为字符串,调用其toString方法,得到:
"" + "[object Object]" = "[object Object]"

2.1+{}
同样满足第三条规则,结果为
"1" + "[object Object]" = "1[object Object]"

3.'1' + false
其中false满足第4条规则,但同时满足第2条规则'1'是字符串,优先处理第2条规则。所以处理结果应该是将false转为字符串
"1" + "false" = "1false"

看看题目中的
{} + []
按规则计算结果应该是
"[object Object]"
但是控制台打印出来的结果却是0,别忘了第5条,当{}+开头的时候,{}并不参与计算,只是被单做一个空的代码块,所以{}+[]实际上是+[], 即Number([]) => Number("") => 0

那么{}+{}就是+{},等于Number({}) => Number("[object Object]") => NaN 然而我们看到结果再次出乎我们的意料,控制台输出的是
"[object Object][object Object]"
到底是怎么回事?

原来对于{}+{}
不同浏览器会有不同的处理结果,在chrome中会输出"[object Object][object Object]",在firefox会输出NaN
这应该是不同浏览器的js引擎解析差异引起的。我们只要记住这个特殊情况就行了。

其实这些特殊值的计算我们平时都很少接触到,也没有多大的意义。关键还是要加深对JS中对数值转换的理解,以不变应万变。到真正遇到问题的时候,不至于摸不着头脑。

@GragonBigX
Copy link

减法、乘法、除法都是先转数字,再计算-。-

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants