原文链接:https://jsisweird.com/(推荐有兴趣可以做一下,体验一下被虐的感觉,不想被虐接着往下看吧? )
前言
JavaScript是一种很棒的变成语言,但是但由于它的初始版本是在 1995 年仅用十天时间构建的,再加上 JS 向后兼容的原因,就导致有很多地球人无法理解的语法?。它并不总是会你想象的那样执行。您将看到 25 个古怪的表达式,即使您是一名 JS 开发人员,大部分的语法我也不希望你在日常开发中使用。
1. true + false
A. ‘truefalse’
B. 1
C. NaN
D. SyntaxError
Output: 1
------
就是简单的类型转换不翻译了
Number(true); // -> 1
Number(false); // -> 0
1 + 0; // -> 1
复制代码
2. [,,,].length
A. 0
B. 3
C. 4
D. SyntaxError
Output: 3
------
[,,,]输出一个包含三个空槽的数组。最后一个逗号是尾随逗号
(sometimes called "final commas"只是个结束)
如果你还是不理解可以看下面:
[,] + [,]; // -> ""
[] + [] === [,] + [,]; // -> true
[,,,] + [,,,]; // -> ",,,,"
([,,,] + [,,,]).length === [,,,,].length; // -> true
复制代码
3. [1, 2, 3] + [4, 5, 6]
A. ‘123456’
B. ‘1,2,34,5,6’
C. ‘1,2,3,4,5,6’
D. SyntaxError
Output: '1,2,34,5,6'
------
答案非常简单,就是将数组转换为字符串,然后进行拼接。
顺便说一下,添加尾随逗号不会有任何改变:
[1, 2, 3,] + [4, 5, 6]; // -> "1,2,34,5,6"
如果您真的想将数组转换为逗号分隔的字符串并将它们组合起来,您可以编写如下愚蠢的代码:
[1, 2, 3] + [, 4, 5, 6]; // -> "1,2,3,4,5,6"
或者,更愚蠢的是,这个:
[1, 2, 3, ""] + [4, 5, 6]; // -> "1,2,3,4,5,6"
复制代码
4. 0.2 + 0.1 === 0.3
A. true
B. false
C. NaN
D. SyntaxError
Output: false
------
这是比较浮点值的困境。与其直接比较两个浮点数,不如将浮点数与某种程度的容差进行比较。
0.2 + 0.1; // -> 0.30000000000000004;
0.2 + 0.1 > 0.3; // -> true (这个真的是太蠢了?)
复制代码
5. 10,2
A. 10.2
B. 10
C. 2
D. 20
Output: 2
------
不懂的建议看一下逗号操作符的用法,逗号操作符就是返回最后一个值
10, 2; // -> 2
1, 2, 3, 4; // -> 4
42, "pineapple", true; // -> true
复制代码
6. !!””
A. true
B. false
C. undefined
D. SyntaxError
Output: false
------
您可以在任何值之前添加两个感叹号以获取其布尔表示。通常,任何有值的都是真,任何有“空”值的都是假。
Boolean(""); // -> false
Boolean(0); // -> false
Boolean("Pineapple"); // -> true
Boolean(42); // -> true
复制代码
7. +!![]
A. true
B. false
C. 0
D. 1
Output: 1
------
在上面的解释中,提到空值通常由布尔值 false 表示。但是,空数组是一个例外。它由 true 表示。然后加号字符将 true 转换为其数字表示。
Boolean([]); // -> true
Number(true); // -> 1
复制代码
8. !!!true
A. true
B. false
C. 0
D. SyntaxError
Output: false
------
连续放置三个或更多感叹号是非常沙雕的,因此您之前可能没有注意到到您甚至可以这样做。
但是,既然你已经写出这么沙雕的代码了,为啥不尝试一下更多感叹号呢哈哈哈哈
!!!!!!!!!!!!true; // -> true
复制代码
9. true == “true”
A. true
B. false
C. undefined
D. SyntaxError
Output: false
------
这两个值都转换为数字。
Number(true); // -> 1
Number("true"); // -> NaN
1 == NaN; // -> false
复制代码
10. 010 – 03
A. 7
B. 5
C. 3
D. NaN
Output: 5
------
010 被 JavaScript 视为八进制数。因此,它的值以 8 为基数。
010; // -> 8
03; // -> 3
8 - 3; // -> 5
如果您愿意沙雕,您可以全力以赴的沙雕:
01111111111111111; // -> 40210710958665
顺便说一下,前面零的数量无关:
010 === 0000000010; // -> true
复制代码
11. “” – – “”
A. ”
B. 0
C. NaN
D. SyntaxError
Output: 0
------
这两个空字符串都转换为 0。
Number(""); // -> 0
0 - - 0; // -> 0
如果我这样写,表达式可能会变得更清晰一些:
+"" - -"";
+0 - -0;
请注意,虽然我在减号和空字符串之间放置空格只是为了让你蒙圈,但减号之间的空格本身很重要:
- -""; // -> 0
--""; // -> SyntaxError
复制代码
12. null + 0
A. 0
B. ‘null0’
C. NaN
D. TypeError
Output: 0
------
Null 转换为其数字表示形式:0。
Number(null); // -> 0
0 + 0; // -> 0
这也意味着,虽然...
null === false; // -> false
... 这是真的:
+null === +false; // -> true
复制代码
13. 0/0
A. 0
B. Infinity
C. NaN
D. SyntaxError
Output: NaN
------
由于方程 0/0 没有有意义的数字答案,因此输出只是NaN。
isNaN(0/0); // -> true
复制代码
14. 1/0 > Math.pow(10, 1000)
A. true
B. false
C. NaN
D. SyntaxError
Output: false
------
JavaScript 将这两个值都视为无穷大,无穷大等于无穷大。
1/0; // -> Infinity
Math.pow(10, 1000); // -> Infinity
Infinity > Infinity; // -> false
复制代码
15. true++
A. 2
B. undefined
C. NaN
D. SyntaxError
Output: SyntaxError
------
首先undefined++不会导致 SyntaxError:
1++; // -> SyntaxError
"x"++; // -> SyntaxError
undefined++; // -> NaN
当然,为了完全清楚,这是有效的语法:
let _true = true;
_true++;
_true; // -> 2
复制代码
16. “” – 1
A. ‘1’
B. ‘-1’
C. -1
D. NaN
Output: -1
------
加法运算符 (+) 用于数字和字符串,减法运算符 (-) 不用于字符串,因此 JavaScript 将其解释为数字之间的运算。空字符串转换为 0。
Number(""); // -> 0
0 - 1; // -> -1;
即使字符串内部有空格(或更多),这仍然是正确的:
" " - 1; // -> -1;
但是,如果我们使用加法运算符,则字符串连接优先:
"" + 1; // -> "1";
复制代码
17. (null – 0) + “0”
A. ‘null0’
B. ’00’
C. 0
D. NaN
Output: '00'
------
Number(null) - 0; // -> 0
0 + "0"; // -> "00"
如果只使用了减法运算符,结果就会不同:
(null - 0) - "0"; // -> 0
复制代码
18. true + (“true” – 0)
A. 1
B. 2
C. NaN
D. SyntaxError
Output: NaN
------
没啥好说的,JS将字符串转换为数字并失败。
Number("true"); // -> NaN
复制代码
19. !5 + !5
A. 0
B. 10
C. 25
D. NaN
Output: 0
------
所有正数都由布尔值 true 表示。true 取反是 false,false 转换为 0。
Boolean(5); // -> true
!true; // -> false
Number(false); // -> 0
0 + 0; // -> 0
复制代码
20. [] + []
A. []
B. [,]
C. ”
D. NaN
Output: ''
------
JavaScript 将数组转换为字符串。
[].toString(); // -> ""
"" + ""; // -> ""
由于尾随逗号,这些表达式是相等的:
[] + [] === [,] + [,]; // -> true
尽管这些数组不同,但它们都被转换为空字符串:
[].length; // -> 0
[,].length; // -> 1
[].toString() === [,].toString(); // -> true
当然,这也可以:
Number([]) === Number([,]); // -> true
复制代码
21. NaN === NaN
A. true
B. false
C. TypeError
D. SyntaxError
Output: false
------
这是由于 IEEE-754 委员会出于一些原因做出的决定/
另外,虽然 NaN 可能不等于它自己......
NaN === NaN; // -> false
……但是下面这两个说法是对的。
isNaN(NaN); // -> true
Object.is(NaN, NaN); // -> true
复制代码
22. NaN++
A. NaN
B. undefined
C. TypeError
D. SyntaxError
Output: NaN
------
尝试对 NaN 进行数值运算,只会输出 NaN。
let _NaN = NaN;
_NaN++;
isNaN(_NaN); // -> true
_NaN--;
isNaN(_NaN); // -> true
_NaN *= 10;
isNaN(_NaN); // -> true
复制代码
23. undefined + false
A. ‘undefinedfalse’
B. 0
C. NaN
D. SyntaxError
0utput: NaN
------
虽然 false 可以转换为数字,但 undefined 不能。
Number(false); // -> 0
Number(undefined); // -> NaN
NaN + 0; // -> NaN
但是,undefined可以转换成false:
!!undefined === false; // -> true
这意味着我们其实是可以让undefined 和 false相加的 :
!!undefined + false; // -> 0
复制代码
24. +0 === -0
A. true
B. false
C. TypeError
D. SyntaxError
Output: true
------
正零和负零在 JavaScript 中是相等的。有趣的是,Object.is函数不同意。有几种情况===和Object.is返回结果不一样,这就是其中之一。
Object.is(0, -0); // -> false
复制代码
25. – “” + + “1” * null – [,]
A. 0
B. ‘0’
C. NaN
D. i give up
Output: 0
------
结局总结一下本测验中涵盖的大部分奇怪的语法。让我们一块一块地分解它:
-""; // -> -0
+"1"; // -> 1
Number(null); // -> 0
Number([,]); // -> 0
把它们加在一起:
-0 + 1 * 0 - 0; // -> 0
复制代码