阅读 5185
【面试说】怪异的 JavaScript

【面试说】怪异的 JavaScript

前言

在网上看到一个有趣的测试,访问地址。里面包含了 25 道选择题,每个都是一个简单的表达式,然后让你选择,都是一些 JavaScript 怪异行为的体现,最后网站生成答案和解析,帮助你更好的理解 JavaScript 怪异的行为。

这里我分享 10 道我认为有趣的,希望对大家有所帮助

测试

  1. [,,,].length

    a. 0

    b. 3

    c. 4

    d. SyntaxError

  2. 10,2

    a. 10.2

    b. 10

    c. 2

    d. 20

  3. true == "true"

    a. true

    b. false

  4. 010 - 03

    a. 7

    b. 5

    c. 3

    d. NaN

  5. 1/0 > Math.pow(10, 1000)

    a. true

    b. false

    c. NaN

    d. SyntaxError

  6. 0/0

    a. 0

    b. Infinity

    c. NaN

    d. SyntaxError

  7. true++

    a. 2

    b. undefined

    c. NaN

    d. SyntaxError

  8. true + ("true" - 0)

    a. 1

    b. 2

    c. NaN

    d. SyntaxError

  9. undefined + false

    a. "undefinedfalse"

    b. 0

    c. NaN

    d. SyntaxError

  10. NaN++

    a. NaN

    b. Undefined

    c. TypeError

    d. SyntaxError

答案

  1. [,,,].length

    a. 0

    b. 3

    c. 4

    d. SyntaxError

    解析:b。稀疏数组,[,,] 中间的元素为 empty ,这种我们就称为稀疏数组,我们也可以通过类似 new Array(2) 的方式创建稀疏数组。那为什么不是 4 而是 3 呢?这个跟 JavaScript 的尾后逗号 有关。MDN 中的解析如下:

    尾后逗号 (有时叫做 “终止逗号”)在向 JavaScript 代码添加元素、参数、属性时十分有用。如果你想要添加新的属性,并且上一行已经使用了尾后逗号,你可以仅仅添加新的一行,而不需要修改上一行。这使得版本控制的代码比较(diff)更加清晰,代码编辑过程中遇到的麻烦更少。

    其实这个在我们平时写对象的时候用得比较多(假如 ESlint 允许的话)。

    var object = {
      foo: "bar",
      baz: "qwerty",
      age: 42, // 注意
    };
    复制代码

    其实数组中也一样,这样就不难理解上面的输出了。

    var arr = [
      1,
      2,
      3,
    ];
    
    arr; // [1, 2, 3]
    arr.length; // 3
    复制代码
  2. 10,2

    a. 10.2

    b. 10

    c. 2

    d. 20

    解析:c。逗号操作符只返回最后一个操作符的值。这允许你创建一个复合表达式,在其中计算多个表达式,复合表达式为最后一个表达式的值。在 for 循环中可能会用到。看到评论中没整明白这个的,可以看 MDN

    for (var i = 0, j = 9; i <= 9; i++, j--)
      console.log('a[' + i + '][' + j + '] = ' + a[i][j]);
    复制代码
    function myFunc() {
      var x = 0;
    
      return (x += 1, x); // the same as return ++x;
    }
    复制代码
  3. true == "true"

    a. true

    b. false

    解析:b。根据隐式类型转换的规则。

    Number(true); // -> 1
    Number("true"); // -> NaN
    1 == NaN; // -> false
    复制代码
  4. 010 - 03

    a. 7

    b. 5

    c. 3

    d. NaN

    解析:b。010 被 JavaScript 视为八进制数。因此,它的值是以8为基数的。010 被解析成 8,减 3 得 5。

  5. 1/0 > Math.pow(10, 1000)

    a. true

    b. false

    c. NaN

    d. SyntaxError

    解析:b。两个表达式都是 Infinity。Infinity 两者相等。

    1/0; // -> Infinity
    Math.pow(10, 1000); // -> Infinity
    Infinity > Infinity; // -> false
    复制代码
  6. 0/0

    a. 0

    b. Infinity

    c. NaN

    d. SyntaxError

    解析:由于等式 0/0 是没有有意义的数值答案,输出简单地是 NaN

  7. true++

    a. 2

    b. undefined

    c. NaN

    d. SyntaxError

    解析:d。会存在以下的怪异行为,undefined 不会报错。【这里我也找不到合适的理由去解释】。

    1++; // -> SyntaxError
    "x"++; // -> SyntaxError
    undefined++; // -> NaN
    复制代码

    假如要使它不报错的话,就得:

    let x = true;
    x++;
    x; // -> 2
    复制代码
  8. true + ("true" - 0)

    a. 1

    b. 2

    c. NaN

    d. SyntaxError

    解析:同 3。

    Number("true"); // -> NaN
    复制代码
  9. undefined + false

    a. "undefinedfalse"

    b. 0

    c. NaN

    d. SyntaxError

    解析:false 可以转换为数字,undefined 不能。

    Number(false); // -> 0
    Number(undefined); // -> NaN
    NaN + 0; // -> NaN
    复制代码

    但是 undefined 又可以转换成 false。

    !!undefined === false; // -> true
    复制代码

    所以要以上为 0。应该:

    !!undefined + false; // -> 0
    复制代码
  10. NaN++

    a. NaN

    b. Undefined

    c. TypeError

    d. SyntaxError

    答案:a。NaN 不是一个数字,所以它不能递增。这也意味着 NaNNaN++ 表示相同的值。

结语

Javascript 之所以有以上怪异表现,主要是初期设计过于匆忙,1995 年仅用用了 10 天来完成的。可能上面的行为我们用得不多,但了解它们对于我们更加深入了解 JavaScript 也是有所帮助。所以强烈建议大家去做一些这 25 道题目,感受一下。

文章分类
前端