JavaScript专业八级测试,你能做对几道?


发布者 ourjs  发布时间 2014-02-12
关键字 求职面试 
注* 本文翻译自JavaScript Puzzlers! do you really know JavaScript? (JavaScript迷题!你真的懂JavaScript吗?) 。本文考察了很多JavaScript中生僻冷门用法和许多容易忽视混淆的概念,据多名Hacker News网友回复,做第二遍依然无法全部答对,jser专家们可以尝试一下。


  1. ["1", "2", "3"].map(parseInt)

    你实际上得到的应该是 [1, NaN, NaN] 因为 parseInt 需要两个参数 (val, radix) 但 map 传了 3 个 (element, index, array)

  2. [typeof null, null instanceof Object]

    typeof 对原生非可调用对象会始终返回 "object"

  3. [ [3,2,1].reduce(Math.pow), [].reduce(Math.pow)] ]

    根据规范: 在一个空数组上应用reduce会抛初始化错误的异常 TypeError

  4.       var val = 'smtg';
          console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing');
        

    它实际上会打印 'Something' 这个 + 操作符的优先级实际上比三元操作符要高.

  5.     var name = 'World!';
        (function () {
          if (typeof name === 'undefined') {
            var name = 'Jack';
            console.log('Goodbye ' + name);
          } else {
            console.log('Hello ' + name);
          }
        })();
        

    var 声明的作用域在整个 function 中, 但并没有初始化

  6.     var END = Math.pow(2, 53);
        var START = END - 100;
        var count = 0;
        for (var i = START; i <= END; i++) {
          count++;
        }
        console.log(count);
        

    这段代码会进入死循环, 2^53 是javascript中最大的数字, 2^53+1 与 2^53 等同, 因此 i 永远也不会比这个数大

  7.     var ary = [0,1,2];
        ary[10] = 10;
        ary.filter(function(x) { return x === undefined;});
        

    Array.prototype.filter 不会应用到缺少的元素上

  8.     var two   = 0.2
        var one   = 0.1
        var eight = 0.8
        var six   = 0.6
        [two - one == one, eight - six == two]
        

    JavaScript 没有精确的数字, 即便它看上去有时侯能正常工作

  9.     function showCase(value) {
          switch(value) {
            case 'A':
              console.log('Case A');
              break;
            case 'B':
              console.log('Case B');
              break;
            case undefined:
              console.log('undefined');
              break;
            default:
              console.log('Do not know!');
          }
        }
        showCase(new String('A'));
        

    switch 使用 === 来枚举,并且 new String(x) !== x

  10.     function showCase2(value) {
          switch(value) {
          case 'A':
            console.log('Case A');
            break;
          case 'B':
            console.log('Case B');
            break;
          case undefined:
            console.log('undefined');
            break;
          default:
            console.log('Do not know!');
          }
        }
        showCase(String('A'));
        

    String(x) 不会返回一个 object 但会返回一个 string, 例如 typeof String(1) === "string"

  11.     function isOdd(num) {
          return num % 2 == 1;
        }
        function isEven(num) {
          return num % 2 == 0;
        }
        function isSane(num) {
          return isEven(num) || isOdd(num);
        }
        var values = [7, 4, '13', -9, Infinity];
        values.map(isSane);
        

    Infinity % 2 返回 NaN, -9 % 2 返回 -1

  12.     parseInt(3, 8)
        parseInt(3, 2)
        parseInt(3, 0)
        

    32进制中不存在, 很显然结果是NaN, 但0呢? parseInt 猜测你的意思是10, 所有返回是3.

  13. Array.isArray( Array.prototype )

    Array.prototype 是一个 Array.

  14.     var a = [0];
        if ([0]) { 
          console.log(a == true);
        } else { 
          console.log("wut");
        }
        

    [0] 被认为是真的,但跟 true 又不等同

  15. []==[]

    == 很邪恶

  16.     '5' + 3  
        '5' - 3
        

    Strings 知道怎么用+, 但是遇到-会被转化为数字

  17. 1 + - + + + - + 1 

    很有意思吧?(我也不清楚)

  18.     var ary = Array(3);
        ary[0]=2
        ary.map(function(elem) { return '1'; });
        

    结果是["1", undefined * 2], 因为map 只能被初始化过的数组成员调用

  19.     function sidEffecting(ary) { 
          ary[0] = ary[2];
        }
        function bar(a,b,c) { 
          c = 10
          sidEffecting(arguments);
          return a + b + c;
        }
        bar(1,1,1)
        

    结果是 21, 在javascript中变量中 arguments 是个对象,所以arguments 和局部变量所引用的内容是一样的。 注* 使用 use strict 可避免这种情况,参见:为什么使用"use strict"可以节约你的时间

  20.     var a = 111111111111111110000,
        b = 1111;
        a + b;
        

    不精确的JavaScript数字即会影响小数,也会影响大数

  21. Number.MIN_VALUE > 0

    Number.MIN_VALUE 是最小的比0大的数, -Number.MAX_VALUE 可能会返回给你一个最大的负整数

  22. [1 < 2 < 3, 3 < 2 < 1]

    隐式转换

  23.     2 == [[[2]]]
        

    每一个对象都被转换成了string,最终成了 "2"

  24.     3.toString()
        3..toString()
        3...toString()
        

    3.x "3" 带上尾数xtoString是合法的, 但空字符串不是

  25.     (function(){
          var x = y = 1;
        })();
        console.log(y);
        console.log(x);
        

    y自动被声明成全局变量, 不在function的域里面.

  26.     var a = /123/, b = /123/;
        a == b
        a === b
        

    根据规范:正则表达式不能比较,因为每个正则都是唯一的。

  27.     var a = [1, 2, 3],
            b = [1, 2, 3],
            c = [1, 2, 4]
        a ==  b
        a === b
        a > c
        a < c
        

    数组通过><会安顺序比较, 但=====不会;

  28.     var a = {}, b = Object.prototype;
        [a.prototype === b, Object.getPrototypeOf(a) === b]
        

    Functions 有一个 prototype 属性,但是其它对象没有,所以 a.prototypeundefined.
    每个 Object 有一个内部的属性可通过Object.getPrototypeOf 访问

  29.     function f() {}
        var a = f.prototype, b = Object.getPrototypeOf(f);
        a === b
        

    f.prototype 是任何被创建出来对象的父对象, 但 new f 会返回 Object.getPrototypeOf 继承的父对象

  30.     function foo() { }
        var oldName = foo.name;
        foo.name = "bar";
        [oldName, foo.name]
        

    name 只读属性. 但是赋值时为什么不会报错呢?我不知道。

  31. "1 2 3".replace(/\d/g, parseInt)

    String.prototype.replace 实现上每组传入的参数为 1, 0, 2, 2, 3, 4.

  32.     function f() {}
        var parent = Object.getPrototypeOf(f);
        f.name // ?
        parent.name // ?
        typeof eval(f.name) // ?
        typeof eval(parent.name) //  ?
        

    function 原型对象被定义在其它地方, 有名字, 可以被执行, 但不在当前的作用域中

  33.     var lowerCaseOnly =  /^[a-z]+$/;
        [lowerCaseOnly.test(null), lowerCaseOnly.test()]
        

    参数被会转换成字符, 因此参数为 "null""undefined".

  34. [,,,].join(", ")

    JavaScript在数组中允许最后一个为逗号,所以原来的那个数组定义了3个 undefined

  35.     var a = {class: "Animal", name: 'Fido'};
        a.class
        

    答案是: 输出需要看是什么浏览器 class 是保留字, 在chrome Firefox 和 Opera中可作为属性名, 但IE不行. 另一方面他们都可以接受其他保留字 (例如 int, private, throws) 作为变量,但class不行.





回复 (82)
  • #
  • #1 最美的时光 2014-02-12 23:51:55
    很多都没有实用价值……
  • #2 霓裳洛羽 2014-02-13 01:16:48
    @最美的时光

    如果能把有实用价值的都做对也挺NB的。
  • #3 蝶姐yrzhll 2014-02-13 06:23:29
    第17题是因为javascript的加法和减法计算是从左到右计算 1 + - (+ (+ (+ (- + 1)))) 最后变成1+1 加法的优先级应该高于自增++ 所有先执行加法 我猜的 嘻嘻
  • #4 蝶姐yrzhll 2014-02-13 06:34:46
    @蝶姐yrzhll

    错了 从右往左计算
  • #5 城南往事v5 2014-02-13 06:45:04
    9 / 26 of 35这是我做的结果,悲惨
  • #6 借个火点烟123 2014-02-13 06:45:55
  • #7 chrome 2014-02-13 07:00:00
    35 / 0 of 35
  • #8 风吹裤裆 2014-02-13 07:29:18
    结果在哪里看?
  • #9 心丨淡然 2014-02-13 07:55:57
    14 / 21 of 35
  • #10 qq142822203 2014-02-14 03:41:53
    13 / 22 of 35
  • #11 keatkeat 2014-02-14 09:40:59
    8 / 27 of 35 很多特性规范都不太明白,但在开发上还不算有很大的影响,对语法学习倒不少!学习了!
  • #12 爱还逝 2014-02-14 09:52:40
    @qq142822203

    去1
  • #13 爱还逝 2014-02-14 09:52:49
    @qq142822203

    13qwefrq
  • #14 月光魔术师 2014-02-15 03:18:03
    有些是ECMA 1.6以上的规范了,确定所有浏览器都能使用?
  • #15 雪片 2014-02-15 03:19:36
    0.8 - 0.6 为什么计算结果是 0.20000000000000007 ,谁能告诉我
  • #16 我没什么好懂的 2014-02-15 03:33:39
    8 / 27 of 35
  • #17 高调离席 2014-02-15 09:41:34
    [/给力]
  • #18 施主贫僧还想要 2014-02-15 13:05:11
    好神奇的东西,拿去装高手不错
  • #19 无泪的遗憾jackieli 2014-02-16 07:47:08
    确实是高手的专属题
  • #20 Johnson 2014-02-16 14:10:38
    26 / 9 of 35
  • #21 qq143803921 2014-02-18 02:45:09
    10/25 of 35
  • #22 omee 2014-02-18 03:55:31
    16 / 19 of 35 蒙的
  • #23 雪花 2014-02-18 06:57:57
    @最美的时光

    很多东西不是为了用,而是为了避免和发现bug,javascript对于新手来说最大的问题是出了bug都不知道怎么回事。
  • #24 有梦才飞翔 2014-02-19 05:12:02
    说没有价值的都在一线,有参考价值的都在上学。。。
  • #25 有梦才飞翔 2014-02-19 05:12:04
    说没有价值的都在一线,有参考价值的都在上学。。。
  • #26 貘吃馍香 2014-02-19 08:28:40
    @蝶姐yrzhll

    不是加减法计算。简单的说。1 + 为一元运算表达式,其后可以接数字。由于后面是 + 它有二义性,首先是 + 运算符,这里符合语法,其后是表示正数的 + ,此时为 1 + 正数后跟number。但是后面又是 + 依然是表示正数,同理 - 为负数,符合 正负性符号+数字的语法规范,以此类推到遇到数字,为一个完整的数字字母量。如:- - - - -+-+-1 为 -1。注意,这里空格很重要,是为了规避 ++ -- 自增减字面量解析,否则会被认为是 -- 或 ++ 一元运算符,导致语法错误。
  • #27 青春的年少轻狂 2014-02-20 03:11:26
    8 / 27 of 35
  • #28 蓝灵 2014-02-20 03:39:58
    11 / 23 of 35
  • #29 限迷恋 2014-02-20 08:14:18
    第七题的结果是0,1,2,,,,,,,,10,丢人呢!
  • #30 redstone 2014-02-26 04:13:22
    我只想说这些是研究javascript的人会就行了,工程化的代码里谁这么写,直接开除就可以了。
  • #31 网事轻尘 2014-03-07 10:08:00
    10 / 24 of 35
  • #32 就喜欢这种范儿 2014-03-17 08:32:50
    29 / 6 of 35
  • #33 搜狐新人758119 2014-03-19 03:37:50
    @蝶姐yrzhll

    因为++不能应用在数字上,只能用在变量上的
  • #34 有田十三 2014-03-24 06:24:44
    11/24
  • #35 冰山之脚 2014-04-01 07:11:31
    有很多还是有价值的。
  • #36 冰山之脚 2014-04-01 07:11:52
    @冰山之脚

    23 / 12 of 35
  • #37 zjhiphop 2014-04-01 11:03:11
    32 / 2 of 35
  • #38 搜狐网友96315668 2014-05-28 05:57:58
    5 / 30 of 35
  • #39 lively_silence 2014-08-07 05:46:29
    • **列表**hjnhnjyjyujuyj

  • #40 cool_violet 2014-08-07 05:46:59
    • 列表
  • #41 cool_violet 2014-08-07 05:47:44
    • ujujuj


    juuujujuj## juj ##

  • #42 frosty_smoke 2014-08-15 12:08:04

    @最美的时光 #0、、 面试如果问这些的我看都不靠谱

  • #43 连云无 2014-11-16 02:21:30

    @雪片 #14

    貌似是计算机进制的转换,数字的精确性会不对,具体的要去算。

  • #44 宁仓比 2014-12-03 00:23:51

    @雪花 #22

  • #45 16 2014-12-28 08:16:28

    13 / 22 of 35

  • #46 16 2014-12-28 08:32:16

    @雪片 #14

    js 的数字都是浮点型,是按照IEEE754规范的,

    首先要知道,计算机存储的信息只有1和0,对于一个具体的数字,计算机有可能并不能精确表述该数字,这样就会有误差,计算的过程当中因为一些操作,也会导致最终的结果有误差

  • #47 哇哈哈 2015-01-21 05:31:30

    打开控制台,所有的答案都写在按钮的样式里面。是否有问题呢? 例如第9题:代码

    Case A Case B Do not know! undefined

    这里都定义了correct样式了

  • #48 ourjs 2015-01-21 07:35:11

    @哇哈哈 #46

    这是BootStrap的默认样式,是后来加上的,答案并无问题。

  • #49 俞屯匆 2015-01-29 02:46:26

    第五题,我测试了一下,如果: var name ="world"; (function(){ console.log(typeof name === "undefined"); })(); 输出的是false 也就是说会走else啊 为什么还是Goodbye呢

  • #50 睡觉 2015-01-30 15:43:35

    两位数的题号。。。样式需要修改

  • #51 孟成儿 2015-02-01 03:30:07

    15 / 20 of 35

  • #52 谢化北 2015-06-12 05:41:45

    14 / 20 of 35

  • #53 陈公伪 2015-07-09 10:36:03

    20/15 of 35

  • #54 江会会 2015-07-14 05:10:02

    18

  • #55 欧丢血 2015-07-27 06:33:52

    哇咔咔

  • #56 Alice 2015-09-04 07:44:52

    23/12 of 35~

  • #57 Alice 2015-09-04 10:43:07

    @就喜欢这种范儿 #31

    大神你好。

  • #58 sandra 2015-09-21 09:18:51

    6 / 22 of 35

  • #59 zpxiaomi 2015-09-30 08:56:33

    @俞屯匆 #48

    这题的关键在于在name在匿名函数里又被声明了一次,我们知道在javascript的同一个scope里多次声明同一个变量相当于一次声明,不会重新初始化变量值。 但是在两个不同的scope: 一个是全局变量name,另一个是匿名函数里的变量name,两者是不同的。由于hoisting的效果,匿名函数内部的name声明会提前到if判断之前,所以这里的if判断的是匿名函数内部的name而不是全局变量name,而在判断时局部变量name并未赋值(仅仅声明被前提),所以判断undefined 为ture,走第一个condition

  • #60 帷幕 2015-11-24 16:55:20

    18/35

  • #61 符幻奸 2015-12-07 05:00:26

    对了14道,哎

  • #62 嘿嘿嘿 2016-02-01 04:39:45

    16哎

  • #63 殷大伪 2016-02-20 08:50:41

    9/26 of 35

  • #64 褚加门 2016-02-22 05:34:31

    点完几道题, 就没兴趣了,我太弱了

  • #65 邬充贝 2016-04-11 09:31:23

    17 / 18 of 35

  • #66 无怨无悔 2016-04-19 09:28:48

    12 / 23 of 35, 使用JS快4年了,好丢人

  • #67 幻精灵 2016-07-05 09:24:14

    13 / 22 of 35,哈哈~惨!

  • #68 叶归关 2016-07-05 10:13:47

    1 - - 1 = 2

  • #69 赵扔凤 2016-07-05 12:50:27

    @雪片 #14

    浮点数吧

  • #70 幻精灵 2016-07-08 09:45:51

    @叶归关 #67

    此题,我总结了个规律: 首先,忽略所有的+号, 得到: 1 - - 1 然后 - - 得正,成为 + 号,得到:1 1 把最后的操作数相加,即为结果

  • #71 康入匠 2016-07-13 06:25:49

    15/20

  • #72 丁帅州 2016-11-17 15:47:50

    没人发现第 32 题答案错了吗?

  • #73 庄为永 2016-12-16 08:01:27

    20 / 15 of 35

  • #74 童欠团 2017-02-23 02:16:09

    @蝶姐yrzhll #2 不对

  • #75 廖正吊 2017-04-18 13:48:19

    28 / 7 of 35

  • #76 霍耳考 2017-06-06 04:55:14

    @雪片 #14

    因为JS中对小数不太精确,太大的数字也不精确

  • #77 李历史 2017-07-21 10:45:02

    9 / 26 of 35

  • #78 Bat3Q 2017-08-16 04:45:03

    陌生的js让我窒息,然而更多的学习,让我们飞舞!

  • #79 车升丑 2017-09-07 09:04:02

    确实,很多都没有实用价值

  • #80 周竹在 2017-11-01 05:09:57

    16 / 19 of 35,第二次做还是错了3道,唉

  • #81 白工反 2018-03-02 02:33:25

    错误:16题, 答案应为 other, 正确的计算 "5" + 3 = "53" 而不是 53,"5" - 3 = 2,因此为 "53", 2

  • #82 赖写甲 2018-03-07 10:39:38

    32题"f","","function","undefined"

微信扫码 立即评论