JavaScript 是一种灵活且有些奇特的语言,有时会让你摸不着头脑。如果你花了一些时间使用 JS,你可能也遇到过一些让人摸不着头脑的情况,比如 0 == "0"
,或者可能也疑惑过为什么 0.1 + 0.2 !== 0.3
。例如,你可能也遇到过这样的情况。
在这篇博文中,我们将探讨一些最让人困惑的 JavaScript 特性,帮助你理解这门语言的内部工作机制,并避开代码中的潜在陷阱。准备好了没?让我们开始!🚀
此处省略了部分内容
1. "False" == 0
但是不是 "False" == "0"
🤯
你可能以为 "False"
等于 "0"
,但这里有个坑:"False" == 0
是真的,但 "False" == "0"
是假的。
这是因为JavaScript的等于操作符(==
)会触发类型转换。当你用字符串和数字进行比较时,JS会先将字符串转换为数字。因为 "False"
并没有对应的数值,它会被转换成 NaN
。而 "0"
则会被转换成数字 0
,所以当我们比较 0 == 0
时,结果为真!
请参阅具体内容
console.log("False" == 0); // true (将字符串 'False' 转换为数字时会变成 NaN,NaN 与 0 比较结果为 false,但最终结果却为 true 由于逻辑转换)
console.log("False" == "0"); // false (字符串 'False' 与字符串 '0' 比较,两者不相等)
全屏模式 退出全屏
此处省略内容
2. 0.1 + 0.2 其实并不等于 0.3,这可真是奇怪了 😂
这个真的经典!
在控制台打印0.1加上0.2是否等于0.3的结果,但会得到false。
全屏模式,退出全屏
为什么会出现这种情况?JavaScript 使用 IEEE-754 进行浮点数运算,这可能会导致精度问题。因此,0.1 + 0.2
并不恰好等于 0.3
。这是在金融应用中常见的一个陷阱,例如,在金融应用中。
解决办法:
在这种情况下进行比较,使用一个较小的容差。
const 是否相等 = Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON;
console.log(是否相等); // 这将输出 true
全屏, 退出
此处省略
3. typeof null
会得到 "object" 🧐
这可真是个难题。当你检查 null
的类型时,它返回 "object"
。
console.log(typeof null); // null的类型是object
进入全屏 退出全屏
为什么这么说呢?这是因为JavaScript早期的一个小失误。null
本应被定义为"null"
类型,但由于一个错误,它被错定义为了"object"
。但现在,如果我们不希望破坏现有的代码,就无法再做更改了。
此处省略内容
4. [1,2,3] + [4,5,6] = "1,2,34,5,6"
😅
这样就把两个列表合并起来了,结果看起来像一个长长的数字串哦 😄
这里还有一个怪事!当你把两个数组加在一起时,JavaScript 会将它们转换为字符串并相加。结果呢?奇怪的拼接!
console.log([1, 2, 3] + [4, 5, 6]); // 将两个数组直接相加会将它们转换为字符串并连接在一起,因此输出为 "1,2,34,5,6"。
全屏模式,退出全屏。
这是因为数组被转换成字符串后,结果是 "1,2,3"
和 "4,5,6"
,当把这些字符串拼接在一起时,就变成了 "1,2,34,5,6"
。
……
5. NaN 与 NaN 不全等
🔄
没错,NaN
(不是数字)在 JavaScript 中是一个特殊的值,而且它永远都不会等于自己。
console.log(NaN === NaN); // NaN 与 NaN 相等的结果是 false. 这段代码输出 false; NaN 表示不是一个数字。
切换到全屏模式,退出全屏
为什么?这样做的逻辑是NaN
不是一个有效的数字,因此它不能与任何数相等,甚至不能与自己相等。
提示:
使用 Number.isNaN()
判断是否为 NaN
。
console.log(Number.isNaN(NaN)); // 检查 NaN 是否为一个非数字值,返回 true
点击此处全屏,点击此处退出全屏
……
6. 为什么[] == ![]
是对而[] == []
是错 😱
在 JavaScript 中,[] == ![]
是真,但 [] == []
是假。这是怎么回事呢?
[] == []
是 假的,因为两个空数组虽然都是空的,但它们是不同的对象,因此不相等。[] == ![]
成立,因为![]
会被转换成false
,而空数组在JavaScript中被视为真值。因此,[] == false
转换后变成true
。
……
7. Math.max() 返回 -无穷大 🤔 你知道吗?
如果你不给 Math.max()
传任何参数,它会返回 -Infinity。
console.log(Math.max()); // 注意,没有参数时,Math.max() 返回 -Infinity,因为没有最大值可以比较。
点击这里全屏。点这里退出全屏。
这是因为 JavaScript 将没有提供参数视为与负无穷大的比较。如果你需要一个备用的值,可以这样做:
const max = Math.max(...numbers) || 0;
这里我们从numbers数组中找出最大值,如果没有找到,就默认为0。
切换到全屏模式 退出全屏
此处留白
8
0 等于 "0",0 也等于 [],不过 "0" 不等于 [] 🔀
JavaScript的==
运算符在类型转换时会干一些奇怪的事。比如,0 == []
是true,但"0" == []
是false。这算是挺奇怪的。
console.log(0 == "0"); // 真
console.log(0 == []); // 真
console.log("0" == []); // 假
切换到全屏模式。退出全屏
这是因为 []
在与 "0"
进行比较时,首先会被转换为空字符串,从而使第二个比较不成立。
此处省略内容
9. 但是 null + 1
会返回 1,而 undefined + 1
则返回 NaN,这让人摸不着头脑。 🤷
这里有一个奇怪的现象。当你把 undefined
和一个数字相加时,你会得到 NaN
值。但是把 null
和一个数字相加会得到 null
。
console.log(undefined + 1); // 结果为NaN
console.log(null + 1); // 结果为1
进入全屏,退出全屏
为什么?undefined
不是一个数字,所以就是 NaN
,而 null
在算术运算中会被当作 0
。
10. 新数组(包含3个元素) vs [,,] 😳
new Array(3)
和 [,,]
之间有什么不同?其中,new Array(3)
创建的是一个长度为3的空数组,而 [,,]
是一个长度为3,但含有两个空位的数组。
new Array(3)
创建了一个空数组,其中包含3个空槽(没有值),而[,,]
创建了一个包含2个未定义值的数组。
console.log(new Array(3)); // [空 x3]
console.log([,, ,]); // [undefined, undefined]
切换到全屏 退出全屏
11. parseFloat("3.14abc")
可以运行,但 parseInt("3.14abc")
不行 😅 你知道吗?
当解析包含数字和文本的字符串时,parseFloat
会读取数字直到遇到第一个非数字字符,而 parseInt
则会在遇到第一个非数字字符时停止,并且不支持小数。
下面的代码展示了如何使用JavaScript中的`parseFloat`和`parseInt`函数处理包含非数字字符的字符串:
console.log(parseFloat("3.14abc")); // 3.14
console.log(parseInt("3.14abc")); // 3
这里,`parseFloat`函数会解析到第一个非数字字符(即"a")之前的所有数字,然后返回一个浮点数。而`parseInt`函数会解析到第一个非数字字符之前的整数部分,然后返回一个整数。
全屏模式,退出全屏
12. [] + {}
和 {}
+ [] 🔄
你知道在JavaScript中运算顺序很重要吗?比如,[] + {}
的结果会变成字符串,但{} + []
则不会产生任何输出。
console.log([] + {}); // 输出 "[对象 对象]"
console.log({} + []); // 输出 "[对象 对象]"
全屏模式。退出。
13. 0.1*0.1 打印“0.010000000000000002” 📐
JavaScript的浮点运算有时会产生意外的结果,像这样在计算 0.1 * 0.1
时会发现:
console.log(0.1 * 0.1); // 结果应该是0.01,但实际输出为0.010000000000000002,这是由于浮点数精度问题引起的。
全屏 退出全屏
这是因为二进制浮点数的精度问题导致的。
14. 真值和假值 🚦
在 JavaScript 里,某些值会被视为 falsy(假值):""
,0
,null
,undefined
,NaN
,和 false
。其他值则被视为 truthy(真值)。
console.log(!!""); // false (即:假)
console.log(!!0); // false (即:假)
console.log(!!null); // false (即:假)
console.log(!!1); // true (即:真)
开启全屏 / 关闭全屏
总之,JavaScript 确实充满惊喜!🎉
现在我们已经了解了一些JavaScript中最奇特的特性和习惯,是时候来检验一下你对这些知识的理解程度了。准备好回答一些难题了吗?🤔
- 为什么
NaN
的typeof
返回 "number",但NaN
并不是一个数值呢? - 在 JavaScript 中,当你执行
Infinity - Infinity
时,你会得到什么?
把答案写在下面哦!看看有几个人能猜对吧!😎