打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
What the f**k JavaScript 中文版

一个有趣和棘手的JavaScript示例列表。

基于个人理解加google翻译,如有问题请指正,谢谢。

JavaScript是一种很好的语言。它有一个简单的语法,庞大的生态系统,以及最重要,最伟大的社区。

同时,我们都知道,JavaScript是一个非常有趣的语言,具有棘手的部分。 他们中的一些可以迅速将我们的日常工作变成地狱,有些可以让我们大声笑起来。

WTFJS的原创思想属于 Brian Leroux. 这个列表受到他的讲话的高度启发 “WTFJS” at dotJS 2012:

目录

💪🏻 动机

只是为了好玩 (tips:我翻译这篇文章同样也是为了好玩)

“只是为了好玩:一个意外革命的故事”, 托瓦兹

这个列表的主要目的是收集一些疯狂的例子,并解释它们如何工作,如果可能的话。 只是因为学习以前不了解的东西很有趣。

如果您是初学者,您可以使用此笔记来深入了解JavaScript。 我希望这个笔记会激励你花更多的时间阅读规范。

如果您是专业开发人员,您可以将这些示例视为您公司新手访问问题和测验的重要资源。 同时,这些例子在准备面试时会很方便。

无论如何,只是读这个。 也许你会为自己找到新的东西。

✍🏻 符号

// -> 用于显示表达式的结果。 例如:

1 + 1 // -> 2

// > 意思是 console.log 或其他输出的结果。 例如:

console.log('hello, world!') // > hello, world!

// 只是一个解释的评论。 例:

// Assigning a function to foo constantconst foo = function () {}

例子

[] 等于 ![]

数组等于一个数组取反

[] == ![] // -> true

说明:

true 是 false

!!'false' == !!'true' // -> true!!'false' === !!'true' // -> true

说明:

考虑一下这一步:

true == 'true' // -> truefalse == 'false' // -> false// 'false' 不是空字符串,所以它的值是true!!'false' // -> true!!'true' // -> true

baNaNa

'b' + 'a' + + 'a' + 'a'

用JavaScript写的老派笑话:

'foo' + + 'bar' // -> 'fooNaN'

说明:

这个表达式可以转化成 'foo' + (+'bar'),但无法将'bar'强制转化成数值

NaN 不是一个 NaN

NaN === NaN // -> false

说明:

规范严格定义了这种行为背后的逻辑:

  1. 如果 Type(x) 不同于 Type(y), return false.
  2. 如果 Type(x) 数值, 然后
    1. 如果 xNaN, return false.
    2. 如果 yNaN, return false.
    3. … … …

7.2.14 严格模式相等比较

遵循IEEE的“NaN”的定义:

四个相互排斥的关系是可能的:小于,等于,大于和无序。 当至少一个操作数是NaN时,最后一种情况出现。 每个NaN都要比较无穷无尽的一切,包括自己。

“对于IEEE754 NaN值的所有比较返回false的理由是什么?” at StackOverflow

它是fail

你不会相信,但...

(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]// -> 'fail'

说明:

将大量的符号分解成片段,我们注意到,以下表达式经常发生:

(![]+[]) // -> 'false'![] // -> false

所以我们尝试将[]false加起来。 但是通过一些内部函数调用(binary + Operator - >ToPrimitive - >[[DefaultValue] ]),我们最终将右边的操作数转换为一个字符串:

(![]+[].toString()) // 'false'

将字符串作为数组,我们可以通过[0]来访问它的第一个字符:

'false'[0] // -> 'f'

现在,其余的是明显的,可以自己弄清楚!

[]true, 但它不等于 true

数组是一个true,但是它不等于true

!![] // -> true[] == true // -> false

说明:

以下是ECMA-262规范中相应部分的链接:

null 是false, 但又不等于 false

尽管 nullfalse ,但它不等于 false

!!null // -> falsenull == false // -> false

同时,其他的一些等于false的值,如 0'' 等于 false

0 == false // -> true'' == false // -> true

说明:

跟前面的例子相同。 这是一个相应的链接:

最小值大于零

Number.MIN_VALUE 是最小的数字,大于零:

Number.MIN_VALUE > 0 // -> true

说明:

Number.MIN_VALUE5e-324 ,即可以在浮点精度内表示的最小正数,即可以达到零。 它定义了最好的分辨率浮标给你。

现在,整体最小的值是 Number.NEGATIVE_INFINITY ,尽管这在严格意义上并不是真正的数字。

“为什么在JavaScript中0小于Number.MIN_VALUE?” at StackOverflow

函数不是函数

V8 v5.5或更低版本中出现的Bug(Node.js <= 7)="">

所有你知道的关于噪声 undefined不是function 。是关于这个吗?

// Declare a class which extends nullclass Foo extends null {}// -> [Function: Foo]new Foo instanceof null// > TypeError: function is not a function// > at … … …

说明:

这不是规范的一部分。这只是一个错误,现在它是固定的,所以将来不会有这个问题。

数组相加

如果您尝试两个数组相加呢?

[1, 2, 3] + [4, 5, 6] // -> '1,2,34,5,6'

说明:

会发生合并。一步一步地,它是这样的:

[1, 2, 3] + [4, 5, 6]// joining[1, 2, 3].join() + [4, 5, 6].join()// concatenation'1,2,3' + '4,5,6'// ->'1,2,34,5,6'

数组中的逗号

您已经创建了一个包含4个空元素的数组。尽管如此,你还是会得到一个有三个元素的,因为后面的逗号:

let a = [,,,]a.length // -> 3a.toString() // -> ',,'

说明:

尾逗号 (有时也称为“最后逗号”) 在向JavaScript代码中添加新元素、参数或属性时有用。如果您想添加一个新属性,您可以简单地添加一个新行,而不用修改以前的最后一行,如果该行已经使用了后面的逗号。这使得版本控制比较清洁和编辑代码可能不太麻烦。

Trailing commas at MDN

数组相等是一个怪物

数组进行相等比较是一个怪物,看下面的例子:

[] == '' // -> true[] == 0 // -> true[''] == '' // -> true[0] == 0 // -> true[0] == '' // -> false[''] == 0 // -> true[null] == '' // true[null] == 0 // true[undefined] == '' // true[undefined] == 0 // true[[]] == 0 // true[[]] == '' // true[[[[[[]]]]]] == '' // true[[[[[[]]]]]] == 0 // true[[[[[[ null ]]]]]] == 0 // true[[[[[[ null ]]]]]] == '' // true[[[[[[ undefined ]]]]]] == 0 // true[[[[[[ undefined ]]]]]] == '' // true

说明:

你应该非常小心,因为上面!这是一个复杂的例子,但它的描述 7.2.13 Abstract Equality Comparison 规范部分。

undefinedNumber

如果我们不把任何参数传递到 Number 构造函数中,我们将得到 0undefined 是一个赋值形参,没有实际的参数,所以您可能期望 NaNundefined 作为参数的值。然而,当我们通过 undefined ,我们将得到 NaN

Number() // -> 0Number(undefined) // -> NaN

说明:

根据规格:

  1. 如果没有参数传递给这个函数,让 n+0 ;
  2. 否则,让 n 调用 ToNumber(value)
  3. 如果值为 undefined,那么 ToNumber(undefined) 应该返回 NaN.

这是相应的部分:

parseInt 是一个坏蛋

parseInt 它以的怪异而出名。

parseInt('f*ck'); // -> NaNparseInt('f*ck', 16); // -> 15

**

说明:

** 这是因为 parseInt 会继续通过解析直到它解析到一个不识别的字符,f'fuck'15进制

解析 Infinity 到整数是什么…

//parseInt('Infinity', 10) // -> NaN// ...parseInt('Infinity', 18) // -> NaN...parseInt('Infinity', 19) // -> 18// ...parseInt('Infinity', 23) // -> 18...parseInt('Infinity', 24) // -> 151176378// ...parseInt('Infinity', 29) // -> 385849803parseInt('Infinity', 30) // -> 13693557269// ...parseInt('Infinity', 34) // -> 28872273981parseInt('Infinity', 35) // -> 1201203301724parseInt('Infinity', 36) // -> 1461559270678...parseInt('Infinity', 37) // -> NaN

小心解析 null

parseInt(null, 24) // -> 23

说明:

它将 null 转换成字符串 'null' ,并尝试转换它。 对于基数0到23,没有可以转换的数字,因此返回NaN。 在24,“n” ,第14个字母被添加到数字系统。 在31,“u” ,添加第21个字母,可以解码整个字符串。 在37处,不再有可以生成的有效数字集,并返回 NaN

“parseInt(null, 24) === 23… wait, what?” at StackOverflow

不要忘记八进制:

parseInt('06'); // 6parseInt('08'); // 0

说明:

这是因为 parseInt 能够接受两个参数,如果没有提供第二个参数,并且第一个参数以 0 开始,它将被解析为八进制数。

truefalse 数学运算

我们做一些数学计算:

true + true // -> 2(true + true) * (true + true) - true // -> 3

嗯…

说明:

我们可以用 Number 构造函数强制转化成数值。 很明显,true 将被强制转换为 1

Number(true) // -> 1

一元加运算符尝试将其值转换成数字。 它可以转换整数和浮点的字符串表示,以及非字符串值 truefalsenull 。 如果它不能解析特定的值,它将转化为 NaN 。 这意味着我们可以更容易地强制将 true 换成 1

+true // -> 1

当你执行加法或乘法时,ToNumber方法调用。 根据规范,该方法返回:

如果 参数 is true , 返回 1 。 如果 参数false 返回 +0

这就是为什么我们可以进行进行布尔值相加并得到正确的结果

相应部分:

HTML注释在JavaScript中有效

你会留下深刻的印象,

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
25个最基本的JavaScript面试问题及答案
Javascript权威指南与高级编程要点记录
JavaScript基础学习目录
20个JS优化代码技巧
最全的JavaScript常见的操作数组的函数方法宝典
C#与C 对比总结之一
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服