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


发布者 ourjs  发布时间 1392214753000
关键字 求职面试 
注* 本文翻译自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 最美的时光 1392249115000
    很多都没有实用价值……
  • #2 霓裳洛羽 1392254208000
    @最美的时光

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

    错了 从右往左计算
  • #5 城南往事v5 1392273904000
    9 / 26 of 35这是我做的结果,悲惨
  • #6 借个火点烟123 1392273955000
  • #7 chrome 1392274800000
    35 / 0 of 35
  • #8 风吹裤裆 1392276558000
    结果在哪里看?
  • #9 心丨淡然 1392278157000
    14 / 21 of 35
  • #10 qq142822203 1392349313000
    13 / 22 of 35
  • #11 keatkeat 1392370859000
    8 / 27 of 35 很多特性规范都不太明白,但在开发上还不算有很大的影响,对语法学习倒不少!学习了!
  • #12 爱还逝 1392371560000
    @qq142822203

    去1
  • #13 爱还逝 1392371569000
    @qq142822203

    13qwefrq
  • #14 月光魔术师 1392434283000
    有些是ECMA 1.6以上的规范了,确定所有浏览器都能使用?
  • #15 雪片 1392434376000
    0.8 - 0.6 为什么计算结果是 0.20000000000000007 ,谁能告诉我
  • #16 我没什么好懂的 1392435219000
    8 / 27 of 35
  • #17 高调离席 1392457294000
    [/给力]
  • #18 施主贫僧还想要 1392469511000
    好神奇的东西,拿去装高手不错
  • #19 无泪的遗憾jackieli 1392536828000
    确实是高手的专属题
  • #20 Johnson 1392559838000
    26 / 9 of 35
  • #21 qq143803921 1392691509000
    10/25 of 35
  • #22 omee 1392695731000
    16 / 19 of 35 蒙的
  • #23 雪花 1392706677000
    @最美的时光

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

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

    因为++不能应用在数字上,只能用在变量上的
  • #34 有田十三 1395642284000
    11/24
  • #35 冰山之脚 1396336291000
    有很多还是有价值的。
  • #36 冰山之脚 1396336312000
    @冰山之脚

    23 / 12 of 35
  • #37 zjhiphop 1396350191000
    32 / 2 of 35
  • #38 搜狐网友96315668 1401256678000
    5 / 30 of 35
  • #39 lively_silence 1407390389664
    • **列表**hjnhnjyjyujuyj

  • #40 cool_violet 1407390419948
    • 列表
  • #41 cool_violet 1407390464783
    • ujujuj


    juuujujuj## juj ##

  • #42 frosty_smoke 1408104484531

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

  • #43 连云无 1416104490380

    @雪片 #14

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

  • #44 宁仓比 1417566231374

    @雪花 #22

  • #45 16 1419754588075

    13 / 22 of 35

  • #46 16 1419755536172

    @雪片 #14

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

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

  • #47 哇哈哈 1421818290774

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

    Case A Case B Do not know! undefined

    这里都定义了correct样式了

  • #48 ourjs 1421825711902

    @哇哈哈 #46

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

  • #49 俞屯匆 1422499586438

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

  • #50 睡觉 1422632615069

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

  • #51 孟成儿 1422761407701

    15 / 20 of 35

  • #52 谢化北 1434087705767

    14 / 20 of 35

  • #53 陈公伪 1436438163965

    20/15 of 35

  • #54 江会会 1436850602562

    18

  • #55 欧丢血 1437978832221

    哇咔咔

  • #56 Alice 1441352692447

    23/12 of 35~

  • #57 Alice 1441363387707

    @就喜欢这种范儿 #31

    大神你好。

  • #58 sandra 1442827131047

    6 / 22 of 35

  • #59 zpxiaomi 1443603393852

    @俞屯匆 #48

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

  • #60 帷幕 1448384120305

    18/35

  • #61 符幻奸 1449464426925

    对了14道,哎

  • #62 嘿嘿嘿 1454301585178

    16哎

  • #63 殷大伪 1455958241569

    9/26 of 35

  • #64 褚加门 1456119271039

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

  • #65 邬充贝 1460367083980

    17 / 18 of 35

  • #66 无怨无悔 1461058128789

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

  • #67 幻精灵 1467710654368

    13 / 22 of 35,哈哈~惨!

  • #68 叶归关 1467713627190

    1 - - 1 = 2

  • #69 赵扔凤 1467723027849

    @雪片 #14

    浮点数吧

  • #70 幻精灵 1467971151372

    @叶归关 #67

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

  • #71 康入匠 1468391149317

    15/20

  • #72 丁帅州 1479397670400

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

  • #73 庄为永 1481875287982

    20 / 15 of 35

  • #74 童欠团 1487816169253

    @蝶姐yrzhll #2 不对

  • #75 廖正吊 1492523299792

    28 / 7 of 35

  • #76 霍耳考 1496724914290

    @雪片 #14

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

  • #77 李历史 1500633902716

    9 / 26 of 35

  • #78 Bat3Q 1502858703143

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

  • #79 车升丑 1504775042402

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

  • #80 周竹在 1509512997047

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

  • #81 白工反 1519958005072

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

  • #82 赖写甲 1520419178733

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

微信扫码 立即评论