• 44 道 JavaScript 难题


    JavaScript Puzzlers原文

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

    1.  
      答案:[1, NaN, NaN]
    2.  
      解析:parseInt (val, radix) :两个参数,val值,radix基数(就是多少进制转换)
    3.  
      map 能传进回调函数 3参数 (element, index, array)
    4.  
      parseInt('1', 0); //0代表10进制
    5.  
      parseInt('2', 1); //没有1进制,不合法
    6.  
      parseInt('3', 2); //2进制根本不会有3
    7.  
      巩固:["1", "1", "11","5"].map(parseInt) //[1, NaN, 3, NaN]

    2. [typeof null, null instanceof Object]

    1.  
      答案:["object", false]
    2.  
      解析:null代表空对象指针,所以typeof判断成一个对象。可以说JS设计上的一个BUG
    3.  
      instanceof 实际上判断的是对象上构造函数,null是空当然不可能有构造函数
    4.  
      巩固:null == undefined //true null === undefined //flase

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

    1.  
      答案:an error
    2.  
      解析:Math.pow (x , y) x 的 y 次幂的值
    3.  
      reduce(fn,total)
    4.  
      fn (total, currentValue, currentIndex, arr)
    5.  
      如果一个函数不传初始值,数组第一个组默认为初始值.
    6.  
      [3,2,1].reduce(Math.pow)
    7.  
      Math.pow(3,2) //9
    8.  
      Math.pow(9,1) //9
    9.  
      [].reduce(Math.pow) //空数组会报TypeError
    10.  
      巩固:[1].reduce(Math.pow) //只有初始值就不会执行回调函数,直接返回1
    11.  
      [].reduce(Math.pow,1) //只有初始值就不会执行回调函数,直接返回1
    12.  
      [2].reduce(Math.pow,3) //传入初始值,执行回调函数,返回9

    4.

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

    这段代码的执行结果?

    1.  
      答案:Something
    2.  
      解析:字符串连接比三元运算有更高的优先级
    3.  
      所以原题等价于 'Value is true' ? 'Somthing' : 'Nonthing'
    4.  
      而不是 'Value is' + (true ? 'Something' : 'Nonthing')
    5.  
      巩固:等我有空总结一下

    5.

    1.  
      var name = 'World!';
    2.  
      (function () {
    3.  
      if (typeof name === 'undefined') {
    4.  
      var name = 'Jack';
    5.  
      console.log('Goodbye ' + name);
    6.  
      else {
    7.  
      console.log('Hello ' + name);
    8.  
      }
    9.  
      })();

    这段代码的执行结果?

    1.  
      答案:Goodbye Jack
    2.  
      解析:(1)typeof时 name变量提升。 在函数内部之声明未定义
    3.  
      2)typeof优先级高于===
    4.  
      巩固:
    5.  
      var str = 'World!';
    6.  
      (function (name) {
    7.  
      if (typeof name === 'undefined') {
    8.  
      var name = 'Jack';
    9.  
      console.log('Goodbye ' + name);
    10.  
      else {
    11.  
      console.log('Hello ' + name);
    12.  
      }
    13.  
      })(str);
    14.  
      答案:Hello World 因为name已经变成函数内局部变量

    6.

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

    这段代码的执行结果?

    1.  
      答案:other ,不是101
    2.  
      解析:js中可以表示的最大整数不是2的53次方,而是1.7976931348623157e+308。2的53次方不是js能表示的最大整数而应该是能正确计算且不失精度的最大整数,
    3.  
      巩固:
    4.  
      var END = 1234567635;
    5.  
      var START = END - 1024;
    6.  
      var c = count = 0;
    7.  
      for (var i = START; i <= END; i++) {
    8.  
      c = count++;
    9.  
      }
    10.  
      console.log(count); //1025
    11.  
      console.log(c); //1024

    7.

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

    这段代码的执行结果?

    1.  
      答案:[]
    2.  
      解析:filter() 不会对空数组进行检测。会跳过那些空元素
    3.  
      巩固:
    4.  
      var ary = [0,1,2,undefined,undefined,undefined,null];
    5.  
      ary.filter(function(x) { return x === undefined;});
    6.  
      // [undefined, undefined, undefined]

    8.

    1.  
      var two = 0.2
    2.  
      var one = 0.1
    3.  
      var eight = 0.8
    4.  
      var six = 0.6
    5.  
      [two - one == one, eight - six == two]

    这段代码的执行结果?

    1.  
      答案:[true, false]
    2.  
      解析:IEEE 754标准中的浮点数并不能精确地表达小数
    3.  
      巩固:var two = 0.2;
    4.  
      var one = 0.1;
    5.  
      var eight = 0.8;
    6.  
      var six = 0.6;
    7.  
      ( eight - six ).toFixed(4) == two
    8.  
      //true

    9.

    1.  
      function showCase(value) {
    2.  
      switch(value) {
    3.  
      case 'A':
    4.  
      console.log('Case A');
    5.  
      break;
    6.  
      case 'B':
    7.  
      console.log('Case B');
    8.  
      break;
    9.  
      case undefined:
    10.  
      console.log('undefined');
    11.  
      break;
    12.  
      default:
    13.  
      console.log('Do not know!');
    14.  
      }
    15.  
      }
    16.  
      showCase(new String('A'));

    这段代码的执行结果?

    1.  
      答案:Do not know!
    2.  
      解析:new String(x)是个对象
    3.  
      巩固:下一题

    10.

    1.  
      function showCase2(value) {
    2.  
      switch(value) {
    3.  
      case 'A':
    4.  
      console.log('Case A');
    5.  
      break;
    6.  
      case 'B':
    7.  
      console.log('Case B');
    8.  
      break;
    9.  
      case undefined:
    10.  
      console.log('undefined');
    11.  
      break;
    12.  
      default:
    13.  
      console.log('Do not know!');
    14.  
      }
    15.  
      }
    16.  
      showCase2(String('A'));

    这段代码的执行结果?

    1.  
      答案:Case A
    2.  
      解析:String('A')就是返回一个字符串

    11.

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

    这段代码的执行结果?

    1.  
      答案:[true, true, true, false, false]
    2.  
      解析:%如果不是数值会调用Number()去转化
    3.  
      '13' % // 1
    4.  
      Infinity % //NaN Infinity 是无穷大
    5.  
      -9 % // -1
    6.  
      巩固: 9 % -2 // 1 余数的正负号随第一个操作数

    12.

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

    这段代码的执行结果?

    1.  
      答案:NaN 3
    2.  
      解析:2进制不可能有3

    13.

    Array.isArray( Array.prototype )
    

    这段代码的执行结果?

    1.  
      答案:true
    2.  
      解析:Array.prototype是一个数组
    3.  
      数组的原型是数组,对象的原型是对象,函数的原型是函数

    14.

    1.  
      var a = [0];
    2.  
      if ([0]) {
    3.  
      console.log(a == true);
    4.  
      else {
    5.  
      console.log("wut");
    6.  
      }

    这段代码的执行结果?

    1.  
      答案:false
    2.  
      解析:[0]的boolean值是true
    3.  
      巩固:a[0] 的boolean是 false

    15.[]==[]

    1.  
      答案:false
    2.  
      解析:两个引用类型, ==比较的是引用地址
    3.  
      巩固:[]== ![]
    4.  
      (1)! 的优先级高于== ,右边运算结果等于 false
    5.  
      (2)一个引用类型和一个值去比较 把引用类型转化成值类型,左边0
    6.  
      (3)所以 0 == false 答案是true

    16.

    1.  
      '5' + 3
    2.  
      '5' - 3

    这段代码的执行结果?

    1.  
      答案:53 2
    2.  
      解析:加号有拼接功能,减号就是逻辑运算

    17. 1 + - + + + - + 1

    1.  
      答案:2
    2.  
      解析:+-又代表正负号, 负负得正。

    18.

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

    这段代码的执行结果?

    1.  
      答案:["1", empty × 2]
    2.  
      解析:如过没有值,map会跳过不会执行回调函数

    19.

    1.  
      function sidEffecting(ary) {
    2.  
      ary[0] = ary[2];
    3.  
      }
    4.  
      function bar(a,b,c) {
    5.  
      c = 10
    6.  
      sidEffecting(arguments);
    7.  
      return a + b + c;
    8.  
      }
    9.  
      bar(1,1,1)

    这段代码的执行结果?

    1.  
      答案:21,
    2.  
      解析:arguments会和函数参数绑定。
    3.  
      但如果es6付给初始值则无法修改
    4.  
      function sidEffecting(ary) {
    5.  
      ary[0] = ary[2];
    6.  
      }
    7.  
      function bar(a=1,b,c) {
    8.  
      c = 10
    9.  
      sidEffecting(arguments);
    10.  
      return a + b + c;
    11.  
      }
    12.  
      bar(1,1,1)
    13.  
      //12

    20.

    1.  
      var a = 111111111111111110000,
    2.  
      b = 1111;
    3.  
      a + b;

    这段代码的执行结果?

    1.  
      答案:11111111111111111000
    2.  
      解析:在JavaScript中number类型在JavaScript中以64位(8byte)来存储。这64位中有符号位1位、指数位11位、实数位52位。2的53次方时,是最大值。其值为:9007199254740992(0x20000000000000)。超过这个值的话,运算的结果就会不对.

    21.

    1.  
      var x = [].reverse;
    2.  
      x();

    这段代码的执行结果?

    1.  
      答案:window
    2.  
      解析:但在chrome上执行报错,没太懂

    22.Number.MIN_VALUE > 0

    1.  
      答案:true
    2.  
      解析:MIN_VALUE 属性是 JavaScript 中可表示的最小的数(接近 0 ,但不是负数)。它的近似值为 5 x 10-324。

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

    1.  
      答案:[true,true]
    2.  
      解析: 1 < 2 => true;
    3.  
      true < 3 => 1 < 3 => true;
    4.  
       
    5.  
      3 < 2 => false;
    6.  
      false < 1 => 0 < 1 => true;

    24.2 == [[[2]]]

    1.  
      答案:true
    2.  
      解析:值和引用类型去比较,把引用类型转话成值类型
    3.  
      [[[2]]])//2

    25.

    1.  
      3.toString()
    2.  
      3..toString()
    3.  
      3...toString()

    这段代码的执行结果?

    1.  
      答案:error, "3", error
    2.  
      解析:因为在 js 中 1.1, 1., .1 都是合法的数字. 那么在解析 3.toString 的时候这个 . 到底是属于这个数字还是函数调用呢? 只能是数字, 因为3.合法啊!

    26.

    1.  
      (function(){
    2.  
      var x = y = 1;
    3.  
      })();
    4.  
      console.log(y);
    5.  
      console.log(x);

    这段代码的执行结果?

    1.  
      答案:1, error
    2.  
      解析:y 被赋值成全局变量,等价于
    3.  
      y = 1 ;
    4.  
      var x = y;

    27.

    1.  
      var a = /123/,
    2.  
      b = /123/;
    3.  
      a == b
    4.  
      a === b

    这段代码的执行结果?

    1.  
      答案:false, false
    2.  
      解析:正则是对象,引用类型,相等(==)和全等(===)都是比较引用地址

    28.

    1.  
      var a = [1, 2, 3],
    2.  
      b = [1, 2, 3],
    3.  
      c = [1, 2, 4]
    4.  
      a == b
    5.  
      a === b
    6.  
      a > c
    7.  
      a < c

    这段代码的执行结果?

    1.  
      答案:false, false, false, true
    2.  
      解析:相等(==)和全等(===)还是比较引用地址
    3.  
      引用类型间比较大小是按照字典序比较,就是先比第一项谁大,相同再去比第二项。

    29.

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

    这段代码的执行结果?

    1.  
      答案:false, true
    2.  
      解析:Object 的实例是 a,a上并没有prototype属性
    3.  
      a的__poroto__ 指向的是Object.prototype,也就是Object.getPrototypeOf(a)。a的原型对象是b

    30.

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

    这段代码的执行结果?

    1.  
      答案:false
    2.  
      解析:a是构造函数f的原型 : {constructor: ƒ}
    3.  
      b是实例f的原型对象 : ƒ () { [native code] }

    31.

    1.  
      function foo() { }
    2.  
      var oldName = foo.name;
    3.  
      foo.name = "bar";
    4.  
      [oldName, foo.name]

    这段代码的执行结果?

    1.  
      答案:["foo", "foo"]
    2.  
      解析:函数的名字不可变.

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

    1.  
      答案:"1 NaN 3"
    2.  
      解析:replace() 回调函数的四个参数:
    3.  
      1、匹配项
    4.  
      2、与模式中的子表达式匹配的字符串
    5.  
      3、出现的位置
    6.  
      4、stringObject 本身 。
    7.  
      如果没有与子表达式匹配的项,第二参数为出现的位置.所以第一个参数是匹配项,第二个参数是位置
    8.  
      parseInt('1', 0)
    9.  
      parseInt('2', 2) //2进制中不可能有2
    10.  
      parseInt('3', 4)
    11.  
      巩固:
    12.  
      "And the %1".replace(/%([1-8])/g,function(match,a , b ,d){
    13.  
      console.log(match +" "+ a + " "+ b +" "+d )
    14.  
      });
    15.  
      //%1 1 8 And the %1

    33.

    1.  
      function f() {}
    2.  
      var parent = Object.getPrototypeOf(f);
    3.  
      f.name // ?
    4.  
      parent.name // ?
    5.  
      typeof eval(f.name) // ?
    6.  
      typeof eval(parent.name) // ?

    这段代码的执行结果?

    1.  
      答案:"f", "Empty", "function", error
    2.  
      解析:f的函数名就是f
    3.  
      parent是f原型对象的名字为"" ,
    4.  
      先计算eval(f.name) 为 f,f的数据类型是function
    5.  
      eval(parent.name) 为undefined, "undefined"

    34.

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

    这段代码的执行结果?

    1.  
      答案:[true, true]
    2.  
      解析:这里 test 函数会将参数转为字符串. 'nul', 'undefined' 自然都是全小写了

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

    1.  
      答案:",,"
    2.  
      解析:因为javascript 在定义数组的时候允许最后一个元素后跟一个,
    3.  
      所以这个数组长度是3,
    4.  
      巩固: [,,1,].join(".").length // 3

    36.

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

    这段代码的执行结果?

    1.  
      答案:other
    2.  
      解析:这取决于浏览器。类是一个保留字,但是它被Chrome、Firefox和Opera接受为属性名。在另一方面,每个人都会接受大多数其他保留词(int,私有,抛出等)作为变量名,而类是VordBoint。

    37.var a = new Date("epoch")

    1.  
      答案:other
    2.  
      解析:您得到“无效日期”,这是一个实际的日期对象(一个日期的日期为true)。但无效。这是因为时间内部保持为一个数字,在这种情况下,它是NA。
    3.  
      在chrome上是undefined
    4.  
      正确的是格式是var d = new Date(year, month, day, hours, minutes, seconds, milliseconds);

    38.

    1.  
      var a = Function.length,
    2.  
      b = new Function().length
    3.  
      a === b

    这段代码的执行结果?

    1.  
      答案:false
    2.  
      解析:首先new在函数带()时运算优先级和.一样所以从左向右执行
    3.  
      new Function() 的函数长度为0
    4.  
      巩固:function fn () {
    5.  
      var a = 1;
    6.  
      }
    7.  
      console.log(fn.length)
    8.  
      //0 fn和new Function()一样

    39.

    1.  
      var a = Date(0);
    2.  
      var b = new Date(0);
    3.  
      var c = new Date();
    4.  
      [a === b, b === c, a === c]

    这段代码的执行结果?

    1.  
      答案:[false, false, false]
    2.  
      解析:当日期被作为构造函数调用时,它返回一个相对于划时代的对象(JAN 01 1970)。当参数丢失时,它返回当前日期。当它作为函数调用时,它返回当前时间的字符串表示形式。
    3.  
      a是字符串 a === b // 数据类型都不同,肯定是false
    4.  
      b是对象 b === // 引用类型,比的是引用地址
    5.  
      c也是对象 a === // 数据类型都不同,肯定是false
    6.  
      巩固: var a = Date(2018);
    7.  
      var b = Date(2001);
    8.  
      [a ===b ]
    9.  
      //[true] Date() 方法获得当日的日期,作为函数调用不需要,返回的同一个字符串
    10.  
      "Tue Jun 12 2018 14:36:24 GMT+0800 (CST)" 当然如果a,b执行时间相差1秒则为false

    40.

    1.  
      var min = Math.min(), max = Math.max()
    2.  
      min < max

    这段代码的执行结果?

    1.  
      答案:false
    2.  
      解析: Math.min 不传参数返回 Infinity, Math.max 不传参数返回 -Infinity
    3.  
      无限集合之间不能比较大小。
    4.  
      巩固:Number.MAX_VALUE > Number.MIN_VALUE //true

    41.

    1.  
      function captureOne(re, str) {
    2.  
      var match = re.exec(str);
    3.  
      return match && match[1];
    4.  
      }
    5.  
      var numRe = /num=(d+)/ig,
    6.  
      wordRe = /word=(w+)/i,
    7.  
      a1 = captureOne(numRe, "num=1"),
    8.  
      a2 = captureOne(wordRe, "word=1"),
    9.  
      a3 = captureOne(numRe, "NUM=2"),
    10.  
      a4 = captureOne(wordRe, "WORD=2");
    11.  
      [a1 === a2, a3 === a4]

    这段代码的执行结果?

    1.  
      答案:[true, false]
    2.  
      解析: /g有一个属性叫lastIndex,每次匹配如果没有匹配到,它将重置为0,如果匹配到了,他将记录匹配的位置。我们看一个简单的例子吧。
    3.  
      var numRe = /num=(d)/g;
    4.  
      numRe.test("num=1abcwewe") //true
    5.  
      numRe.lastIndex //5 匹配到num=1后在5的索引位置
    6.  
      numRe.exec("num=1") //fales 这次要从5的索引位置,开始匹配
    7.  
      numRe.lastIndex //0 上一次匹配失败了numRe.lastIndex重制为0

    42.

    1.  
      var a = new Date("2014-03-19"),
    2.  
      b = new Date(2014, 03, 19);
    3.  
      [a.getDay() === b.getDay(), a.getMonth() === b.getMonth()]

    这段代码的执行结果?

    1.  
      答案:[false, false]
    2.  
      解析: var a = new Date("2014-03-19") //能够识别这样的字符串,返回想要的日期
    3.  
      Wed Mar 19 2014 08:00:00 GMT+0800 (CST)
    4.  
      b = new Date(2014, 03, 19); //参数要按照索引来
    5.  
      Sat Apr 19 2014 00:00:00 GMT+0800 (CST)
    6.  
      月是从0索引,日期是从1
    7.  
      getDay()是获取星期几
    8.  
      getMonth()是获取月份所以都不同
    9.  
      巩固: [a.getDate() === b.getDate()] //true

    43.

    1.  
      if ('http://giftwrapped.com/picture.jpg'.match('.gif')) {
    2.  
      'a gif file'
    3.  
      else {
    4.  
      'not a gif file'
    5.  
      }

    这段代码的执行结果?

    1.  
      答案:'a gif file'
    2.  
      解析: String.prototype.match 接受一个正则, 如果不是, 按照 new RegExp(obj) 转化. 所以 . 并不会转义 。 那么 /gif 就匹配了 /.gif/
    3.  
      巩固: if ('http://giftwrapped.com/picture.jpg'.indexOf('.gif')) {
    4.  
      'a gif file'
    5.  
      else {
    6.  
      'not a gif file'
    7.  
      }
    8.  
      //'a gif file' 同样的道理
  • 相关阅读:
    正确解读free -m
    linux命令总结之traceroute命令
    OSI七层模型详解
    Linux运维七:网络基础
    python contextlib 上下文管理器
    Django扩展自定义manage命令
    Elasticsearch分片、副本与路由(shard replica routing)
    EsRejectedExecutionException排错与线程池类型
    python重试(指数退避算法)
    Redis实现分布式锁
  • 原文地址:https://www.cnblogs.com/7qin/p/9677928.html
Copyright © 2020-2023  润新知