zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    App自动化01-Appium概述
    App绕过SSL Pinning机制抓取Https请求
    手机大厂必备测试技能-GMS 认证
    手机大厂必备测试技能-CTS 兼容测试
    一文搞定web自动化环境常见问题
    Airtest-UI 自动化集大成者
    shell三剑客之sed
    shell三剑客之grep
    二月主题读书整理——元技能系列
    深度学习目标检测综述推荐之 Xiaogang Wang ISBA 2015
  • 原文地址:https://www.cnblogs.com/jjucap/p/7716394.html
Copyright © 2011-2022 走看看