英文 | https://medium.com/frontend-canteen/20-useless-but-funny-challange-for-javascript-developer-9eea39bb8efb
翻译 | 杨小爱
由于JavaScript 是一种容错率极高的编程语言,许多在其他编程语言中非法的表达式在 JavaScript 中都能正常工作,是不是觉得很神奇?
正是因为JavaScript的这个特点,于是,导致很多奇怪的代码,今天我们就一起来看看这些代码, 我一共总结汇总了20个特别有趣有意思的代码题,你敢用它去挑战一下你的朋友同事吗?
在这20个代码题中,我都附加了分析解释,当然,你也可以自己先试一遍,看看你那边的结果如何。
好了,我们现在开始吧。
01、true + false
题目如下:
true + false
分析
当你尝试在两个布尔值之间使用加法运算符 (+) 时,它们将转换为数字。
而且我们都知道 true 应该转换为 1 , false 应该转换为 0 。所以 true + false 返回 1 。
输出结果:
1
02、[,,,].length
[,,,].length
分析
[,,,] 输出一个包含三个空槽的数组,最后一个逗号是尾随逗号。
你可以这样想:
[,] ==> [empty,]
[,,] ==> [empty, empty,]
[,,,] ==> [empty, empty, empty,]
所以 [,,,].length 返回 3。
输出结果:
3
03、[1, 2, 3] + [4, 5, 6]
[1, 2, 3] + [4, 5, 6]
分析
当我们尝试在数组之间使用 add operator(+) 时,它们将转换为字符串。
当我们尝试将数组转换为字符串时,将调用数组的 toString() 方法。当需要将数组显示为文本时,JavaScript 在内部使用 toString() 方法,它将用逗号连接其元素。
[1, 2, 3].toString() ==> '1, 2, 3'
[4, 5, 6].toString() ==> '4, 5, 6
所以,[1, 2, 3] + [4, 5, 6]的结果为:
[1, 2, 3] + [4, 5, 6] ==> '1, 2, 3' + '4, 5, 6' ==> "1,2,34,5,6"
04、0.2 + 0.1 === 0.3
0.2 + 0.1 === 0.3
分析
由于浮点数在计算机中很难准确表示,因此数学上的 0.1 和 0.2 在计算机中只能用近似数来表示。
0.1 + 0.2 的结果并不完全是 0.3。 不只是 JavaScript; 其他编程语言也有同样的问题。
输出结果:
false
想了解更多,可以转到此 StackOverflow 上查看:https://stackoverflow.com/questions/588004/is-floating-point-math-broken
05、10, 2
10,2
分析
逗号 (,) 在 JavaScript 中也是一个合法的运算符,计算它的每个操作数(从左到右),并返回最后一个操作数的值。
所以 10, 2 返回 2。
输出结果:
2
06、!!""
!!""
分析
"" 是一个空字符串,它是一个假值。
注意:0 、 empty string "" 、 null 和 undefined 都是假值。
!是逻辑 NOT 运算符,将真为假,反之亦然。
如果我们使用 ! 两次,就是!!,它将普通值转换为布尔值。所以 !!"" 返回 false。
输出结果为:
false
07、+!![]
+!![]
分析
数组都是真值,甚至是空数组。所以 !![] 将返回 true。
!![]; // -> true
加号字符会将 true 转换为其数字表示:1
+true; // -> 1
所以 +!![] 返回 1 。
输出结果为:
1
08、true == "true"
true == "true"
分析
相等运算符 (==) 检查它的两个操作数是否相等,返回一个布尔结果。
根据抽象相等比较的规则,这两个值在比较时都转换为数字。
true == "true" ==> Number(true) == Number("true") ==> 1 == NaN
所以 ture == "true 返回 false。
false
那么,这段代码的结果是什么?
false == '0'
09、010 - 03
010 - 03
分析
这是一个小技巧:如果一个数字以 0 开头,它在 JavaScript 中被视为八进制数。
所以
010 - 03 ==> 8 - 3 ==> 5
输出结果:
5
还有:
- 如果一个数字以 0b 开头,它在 JavaScript 中被视为二进制数。
- 如果一个数字以 0x 开头,它在 JavaScript 中被视为十六进制数字。
10、"" - - ""
"" - - ""
分析
这看起来像一个错误语法,但它确实工作正常。
空字符串可以转换为布尔值 false 或数值 0 。
所以 -"" 表示 0
此表达式将返回 0。
输出结果:
0
11、null + 0
null + 0
正如我们之前所说,null 是一个假值,它将被转换为布尔值 false 或数值 0
所以它会返回 0。
12、0/0
0/0
这是一个非法的数学表达式,方程 0/0 没有有意义的数字答案,输出只是 NaN。
13、1/0 === 10 ** 1000
1/0 === 10 ** 1000
虽然 1/0 和前面一题一样,也是一个非法的数学表达式。但是当被除数不为 0 时,JavaScript 认为这个表达式的结果是无穷大。
而 10 ** 1000 这么大的数字,JavaScript 无法正确表示这个数字。(JavaScript 中的最高整数值为 2^53–1), 所以 10 * 1000 也被视为无穷大。
Infinity 总是等于另一个 Infinity,所以 1/0 === 10 ** 1000 返回 true。
输出结果:
true
14、true++
true++
这没什么特别的。 这只是一个语法错误。 我们的第一个也是唯一的语法错误。
15、"" - 1
"" - 1
分析
虽然加法运算符 (+) 用于数字和字符串,但减法运算符 (-) 对字符串没有用处,因此 JavaScript 将其解释为数字之间的操作,空字符串被强制转换为 0。
"" - 1 ==> Number("") - 1 ==> 0 - 1 ==> -1
所以 "" -1 返回 -1 :
16、(null - 1) - "1"
(null - 1) - "1"
正如我们之前所说:
null ==> 0
(null - 1) ==> -1
"1" ==> 1
所以 (null - 1) -“1” 返回 -2 :
输出结果:
-2
17、38 * 4343 * 2342+(“true” - 0)
38 * 4343 * 2342+ (“true” — 0)
分析
你可能会怀疑 JS 太疯狂了,以至于它会将字符串文字“true”转换为布尔值 true 的数字表示。实际发生的是它尝试将字符串转换为数字并失败。
Number("true"); // -> NaN
在 JavaScript 数值运算中,只要有一个值为 NaN 的值,运算的最终结果一定是 NaN。38 * 4343 * 2342 只是一个烟雾弹。
输出结果:
NaN
18、5 + !5 + !!5
5 + !5 + !!5
分析
正如我们之前所说:
- 0 、空字符串 "" 、null 和 undefined 都是假值。
- 非零数字是真值。
所以:
5 + !5 + !!5;
输出结果为:
6
19、[] + [1] + 2
[] + [1] + 2
正如我们之前所说:当我们尝试在数组之间使用加法运算符(+)时,它们将被转换为字符串。
[] ==> ''
[1] ==> '1'
[] + [1] ==> '1'
'1' + 2 ==> '12'
所以结果是 '12' 。
最终输出结果为:
"12"
20、1+2+"3"
1 + 2 + "3"
分析
JavaScript 会从左到右执行这些操作。当数字 3 与字符串 3 相加时,字符串连接将优先。
1 + 2; // -> 3
3 + "3"; // -> "33"
因此,输出结果为:
"33"
写在最后
坦率地说,这些代码题对我们的编码技能没有太多价值,并且我们也不应该在实际项目中编写这种代码。
但是,将这些技巧作为我们与朋友同事之间的谈点,这也是些代码的价值,是不是也是一件很有趣的事?
只是,我在实际生活中,我用这些问题来测试我的朋友后,结果我被一群人殴打了一顿,至于你是否需要用它来测试的朋友或者同事,请自行决定。