What the f*ck JavaScript?

额,以下是自己对这篇文章的翻译和理解,有理解不正确的地方还请各位大佬指出。

文章github地址 https://github.com/denysdovhan/wtfjs

自己的地址: https://www.zybuluo.com/phone/note/916113

 WTF JavaScript

 

---

JavaScript是一种伟大的语言。 它有一个简单的语法,大的生态系统,最重要的是一个伟大的社区。
与此同时,我们都知道,JavaScript是一个非常搞笑的语言并且也有着棘手的部分。 有些可以迅速把我们的日常工作变成如入地狱般,有些又可以让我们笑出声来。

WTFJS的最初想法属于Brian Leroux。 这些目录是通过他在2012年dotJS上的讲话“WTFJS”受到的高度启发:

Node Packaged Manuscript
----------------------------
你可以安装使用手册,只要

npm install -g wtfjs
现在你可以在命令行运行wtfjs,它将在手册中打开你选择的页面。你也可以在这里进行阅读。[阅读链接地址][1]

Motivation
----------

> Just for fun
— [“Just for Fun: The Story of an Accidental Revolutionary”][2], Linus Torvalds

这个列表主要的目的是去收集一些疯狂的例子,有可能的话也会解释它们是如何工作的。正因为如此我们能学到以前不了解的东西。
如果您是初学者,您可以使用这些注释来深入了解JavaScript。 我希望这些笔记会激励你花更多的时间阅读规范。
如果您是专业开发人员,您可以将这些示例视为对我们所爱的JavaScript的所有怪异和意想不到的边缘的极大参考。
无论如何,去阅读它吧,你有可能将会发现一些新东西。

Notation(符号说明)
------------
`//->`用于展示表达式的结果,例如:

1 + 1 // -> 2

`//>`表示console.log或者其他的输出,例如

console.log('hellow world') // > hellow world

`//` 这个相信大家都知道,是注释的意思 ,例如

//定义一个函数赋值给foo常量
const foo = function(){}

 

Examples
--------
[] 等于 ![]

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


解释:
[12.5.9 Logical NOT Operator (!)][3]
[7.2.13 Abstract Equality Comparison][4]

> 这里其实是一系列的比较,首先是比较右边的![],因为[]是个空数组,![]就是false, 变成比较[]> ==false,根据es规范中的7.2.13节第七条,对号入座。 变成[] == ToNumber(false);根据7.1.3中的ToNumber()规则,变成[] == 0;
> 回到7.2.13的第九条,变成ToPrimitive([]) == 0;根据规则一步一步下去,结果就是 0 == 0 ,当然return true

**true is false**

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

 

> 个人认为要区分字符串和布尔值就行了 'false'是非空的字符串

**baNaNa**

'b' + 'a' + + 'a' + 'a' // ->baNaNa

 


这是JavaScript中的一个老式的笑话,但是换了个版本。 这是原来的:

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

 

> 给大家说说我理解的这个笑话:foo的意思是fu的变体,fu又是英语习语fuckup的缩写,bar是无法识别的意思。连在一起就是TMD无法识别。你和电脑说:请拼接下这个TMD无法识别,电脑:TMD
> NAN。。。。(哈哈哈哈。。。)

这个表达式实际是为'foo'+(+'bar'),它将'bar'转换为非数字。
解释:
[12.8.3 The Addition Operator (+)][5]
[12.5.6 Unary + Operator][6]

**NaN is not a NaN**

NaN === NaN // -> false

 


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

1.If Type(x) is different from Type(y), return false.
2.If Type(x) is Number, then
If x is NaN, return false.
If y is NaN, return false.
… … …

[----- 7.2.14 Strict Equality Comparison][7]

**It's a fail**
你可能不相信

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

 


解释:
通过将大量的符号分解成块,我们注意到经常出现以下模式:

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

 


所以我们尝试将[]添加为false。 但是由于一些内部函数调用(二进制+运算符 - > ToPrimitive - > [[DefaultValue]]),我们最终将右侧的操作数转换为一个字符串:

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

 

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

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

其余的就很明显,但是这个i很棘手,通过生成字符串“falseundefined”抓取不到index ['10']上的元素

**[] is truthy, but not true**
一个数组是有着真实的值,但是并不等于true

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

以下是ECMA-262规范中相应部分的链接:
[12.5.9 Logical NOT Operator (!)][8]
[7.2.13 Abstract Equality Comparison][9]

**null is falsy, but not false**
尽管null是一个错误的值,但它不等于false。

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

 


同时,其他错误值,如0或“”等于false。

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

 


解释:

> 也是一系列的比较,链接和上面的一样。

**document.all is an object, but it is undefined**
*这是浏览器的一个api,并不会在nodeJs环境下生效*

尽管document.all是一个类数组的对象,它可以访问页面中的DOM节点,但使用typeof函数的结果是未定义。

document.all instanceof Object // -> true
typeof document.all // -> 'undefined'

 

同时,它并不等于自定义

document.all === undefined // -> false
document.all === null // -> false


但相同的:

document.all == null // -> true

 


解释:

> document.all曾经是一种访问DOM元素的方式,与旧版本的IE相似。虽然它从来没有成为一种标准,但它在旧版JS代码中被广泛使用。当新的api被标准委员会提出(像document.getElementById),这个API调用的已经过时了,标准委员必须决定如何处理它。由于它的广泛使用,他们决定保留API,并故意使它违反JavaScript规范。这就是为什么当使用严格的比较对照的规则即“===”( [Strict Equality Comparison][10])时,结果是false。由于明确允许故意违规规范,所以在使用抽象的比较对照规则即“==”([Abstract Equality Comparison][11] )时结果为true

**Minimal value is greater than zero**

Number.MIN_VALUE 是最小的数字, 并且大于0:

Number.MIN_VALUE > 0 // -> true
解释:
Number.MIN_VALUE是5e-324,即可以在浮点精度内表示的最小正数,即尽可能接近于零。现在,整体最小的值是Number.NEGATIVE_INFINITY,尽管它在严格意义上并不是真正的数字。

**function is not function**

所有人都知道烦人的undefined不是一个函数,但是呢?

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

 


解释:
这不是规范的一部分。 这只是一个已经修复的错误,所以今后不应该有问题。

**Adding arrays**
如果你尝试将两个数组相加

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

 


解释:
一步步解析,像下面这样:

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

 


**Trailing commas in array**
您创建了一个包含4个空元素的数组。尽管如此,因为后面的逗号你会得到一个有三个元素的arrary:

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

 


解释:
在JavaScript代码中添加新元素,参数或属性时,逗号(有时称为“最终逗号”)很有用。如果要添加新的属性,如果前一行已经添加了逗号,那么不需要修改前一行,只需要添加新行即可。这使得版本控制差异更清晰,编辑代码可能不那么麻烦。

**Array equality is a monster**
数组比较是JS中的一个怪物。。。

[] == '' // -> 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抽象平等比较部分进行了描述。

**undefined and Number**
如果我们没有将任何参数传递到Number构造函数中,我们将得到0.当没有实际参数时,将undefined赋值给形式参数,因此您可能希望Number(无参数)将undefined定义为其参数的值。但是,当我们通过undefined时,我们将得到NaN。

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

 

解释:
根据以下的规范可以得出:

> 1.If no arguments were passed to this function's invocation, let n be +0.
> 2.Else, let n be ? ToNumber(value).
> 3.In case of undefined, ToNumber(undefined) should return NaN.

 

以上只是其中的一部分,后续的一部分我也会慢慢整理出来。

 


[1]: https://github.com/denysdovhan/wtfjs
[2]: https://en.wikipedia.org/wiki/Just_for_Fun
[3]: https://www.ecma-international.org/ecma-262/#sec-logical-not-operator
[4]: https://www.ecma-international.org/ecma-262/#sec-abstract-equality-comparison
[5]: https://www.ecma-international.org/ecma-262/#sec-additive-operators
[6]: https://www.ecma-international.org/ecma-262/#sec-unary-plus-operator
[7]: https://www.ecma-international.org/ecma-262/#sec-strict-equality-comparison
[8]: https://www.ecma-international.org/ecma-262/#sec-logical-not-operator
[9]: https://www.ecma-international.org/ecma-262/#sec-abstract-equality-comparison
[10]: https://www.ecma-international.org/ecma-262/#sec-strict-equality-comparison
[11]: https://www.ecma-international.org/ecma-262/#sec-abstract-equality-comparison

posted @ 2017-10-23 13:52  麦丽素  阅读(360)  评论(0编辑  收藏  举报