JavaScript Puzzlers!,题目基于ECMA 262 (5.1)的浏览器环境
1.What is the result of this expression? (or multiple ones)
1 | ["1", "2", "3"].map(parseInt) |
考察map
和parseInt
Array.prototype.map()
接收三个参数(element,index,Array)
parseInt()
接收两个参数(val,radix)
,radix
为基数,parseInt('17',8) //15
,radix
为0或无表示以10为基数。每个位上的数字不能比基数大,否则返回NaN
,radix
不能为1,范围为2-36。
1 | parseInt('1',0)//1 |
2.What is the result of this expression? (or multiple ones)
1 | [typeof null, null instanceof Object] |
考察typeof
和instanceof
。
typeof null
返回object
,typeof
对本地不可调用对象均返回object
(包括array, null
), 其他的可能返回的数据是number, string, boolean, object, function, undefined
;instanceof
运算符用于测试构造函数的prototype
属性是否出现在对象的原型链中的任何位置。null
为基本类型,所以null instanceof Object // false
。
选A
3.What is the result of this expression? (or multiple ones)
1 | [ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ] |
考察reduce
函数的用法Array.prototype.reduce()
接收两个参数(function(accumulator, currentValue, currentIndex, array), initialValue)
空数组调用reduce
时没有设置初始值将会报错。
所以选A
4.What is the result of this expression? (or multiple ones)
1 | var val = 'smtg'; |
考察运算符优先级,MDN运算符优先级表
+(13级)优先级大于?(3级),所以'Value is ' + (val === 'smtg')
条件判断为true
,答案为'Something'
,选D
5.What is the result of this expression? (or multiple ones)
1 | var name = 'World!'; |
考察变量声明提升(var hoisting)
由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明。这意味着变量可以在声明之前使用,这个行为叫做“hoisting”。“hoisting”就像是把所有的变量声明移动到函数或者全局代码的开头位置。
所以选A
6.What is the result of this expression? (or multiple ones)
1 | var END = Math.pow(2, 53); |
考察JavaScript中的安全整数范围Number.MIN_SAFE_INTEGER
代表在JavaScript中最小的安全的integer
型数字-(2^53 - 1)
。Number.MAX_SAFE_INTEGER
代表在JavaScript中最大的安全整数(2^53 - 1)
。
这个数字形成的原因是,Javascript 使用 IEEE 754 中规定的double-precision floating-point format numbers
,在这个规定中能安全的表示数字的范围在-(2^53 - 1)
到2^53 - 1
之间,包含-(2^53 - 1)
和2^53 - 1
。
2^53+1 与 2^53超过安全整数范围,2^53+1 === 2^53 //true
,所以为无限循环,选D
7.What is the result of this expression? (or multiple ones)
1 | var ary = [0,1,2]; |
考察filter
函数filter
函数中callback
只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。
所以选C
8.What is the result of this expression? (or multiple ones)
1 | var two = 0.2 |
考察js大数和浮点数精度丢失的问题
计算机的二进制实现和位数限制有些数无法有限表示。就像一些无理数不能有限表示,如 圆周率 3.1415926…,1.3333… 等。JS 遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit。
解决方案:
对于整数,前端出现问题的几率可能比较低,毕竟很少有业务需要需要用到超大整数,只要运算结果不超过 Math.pow(2, 53) 就不会丢失精度。
对于小数,前端出现问题的几率还是很多的,尤其在一些电商网站涉及到金额等数据。解决方式:把小数放到位整数(乘倍数),再缩小回原来倍数(除倍数)
选择C,没有道理,时而准确时而不准,忧伤
9.What is the result of this expression? (or multiple ones)
1 | function showCase(value) { |
考察switch()
和判等switch()
使用===
判等,而new String('A')!=='A'
,所以选C
10.What is the result of this expression? (or multiple ones)
1 | function showCase2(value) { |
考察String()
方法和判等String('A')
没有新建一个对象,而是返回一个string
的基本类型,所以选A
11.What is the result of this expression? (or multiple ones)
1 | function isOdd(num) { |
考察取余操作符
取余操作符保证符号,所以-9 % 2 === -1 , Infinity % 2 => NaN
所以选C
12.What is the result of this expression? (or multiple ones)
1 | parseInt(3, 8) |
考察parseInt()
函数,分析见第1题,答案应该为3,NaN,3
所以选D
13.What is the result of this expression? (or multiple ones)
1 | Array.isArray(Array.prototype) |
考察Array.prototype
,是数组,所以选A
14.What is the result of this expression? (or multiple ones)
1 | var a = [0]; |
考察if()
和判等,见js相等性比较if([])
都会执行,所以if([0])
更会执行,对象和布尔值比较,布尔值转换为数字,对象转换为原始值比较,[0] == true // false
所以选B
15.What is the result of this expression? (or multiple ones)
1 | []==[] |
考察相等性比较,见js相等性比较
对象和对象比较,引用相同返回true
,否则返回false
,所以选B
16.What is the result of this expression? (or multiple ones)
1 | '5' + 3 |
考察+
,-
运算符,字符串会使用+
运算符做连接,但是遇到-
则转换为数值进行运算。
所以选A
17.What is the result of this expression? (or multiple ones)
1 | 1 + - + + + - + 1 |
考察一元+, -
中间一元加号不影响,两个一元减号负负得正变加号,所以选A
18.What is the result of this expression? (or multiple ones)
1 | var ary = Array(3); |
考察map
函数
删除或未赋值的元素不会被遍历到,返回[2, undefiend, undefiend]
,所以选D
19.What is the result of this expression? (or multiple ones)
1 | function sidEffecting(ary) { |
考察函数的arguments
函数的arguments
与参数是相对应的,但不是同一片内存空间,所以答案为21,选D
20.What is the result of this expression? (or multiple ones)
1 | var a = 111111111111111110000, |
考察js的大数精度a > 2^53 -1
, js中的大数精度也缺失了,选B
21.What is the result of this expression? (or multiple ones)
1 | var x = [].reverse; |
题目基于ECMA 262 (5.1)的浏览器环境,[].reverse
返回this
,被浏览器调用之后为window
。
选D
22.What is the result of this expression? (or multiple ones)
1 | Number.MIN_VALUE > 0 |
考察Number
Number.MIN_VALUE
是大于0的最小数,所以选B
23.What is the result of this expression? (or multiple ones)
1 | [1 < 2 < 3, 3 < 2 < 1] |
考察<
运算符(1 < 2) < 3
,1 < 2 //true 转换为1
1 < 3 // true
(3 < 2) < 1
,3 < 2 //false 转换为0
0 < 1 //true
所以选A
24.What is the result of this expression? (or multiple ones)
1 | // the most classic wtf |
考察==
对象和其他值比较时,会将对象转换为原始值,[[[2]]]
转换原始值为2
所以返回true
25.What is the result of this expression? (or multiple ones)
1 | 3.toString() |
我靠了
考察Number
对象中.
表示小数还是使用方法的问题。3.x
表示数字3
后面加上x
的后缀,后缀可以为空,但是不可以为3.toString()
,所以Number
对象若使用toString
方法,必须加上()
,如(3).toString()
,否则表示小数,这题很贼。
选C
26.What is the result of this expression? (or multiple ones)
1 | (function(){ |
考察匿名函数变量定义
连等赋值从右到左进行解析,得到y = 1; var x = y
,所以x
为局部变量,y
为全局变量。
所以选C
27.What is the result of this expression? (or multiple ones)
1 | var a = /123/, |
考察对象比较
两个对象比较==
和===
效果一样的,均比较引用是否相同。
所以选C
28.What is the result of this expression? (or multiple ones)
1 | var a = [1, 2, 3], |
考察数组比较
基于引用值是否相同比较数组对象是否相等,基于标准字典的Unicode值来进行比较数组的大小
选A
29.What is the result of this expression? (or multiple ones)
1 | var a = {}, b = Object.prototype; |
考察原型和原型对象Object.getPrototypeOf()
方法返回指定对象的原型,即实例对象内部的_proto_
属性,即我们常说的原型链,所有对象的原型均从Object
继承而来。如果没有继承属性,则返回 null
(最顶层的Object
)。prototype
为原型对象,只有Function
对象有,其他对象都没有。所以选A。
30.What is the result of this expression? (or multiple ones)
1 | function f() {} |
考察原型和原型对象
函数原型对象:
1 | Function.prototype = { |
而Object.getPrototypeOf()
返回对象的原型即_proto_
,这个属性是对象本身为了实现继承的,是指向父对象的原型对象。选B
函数的原型对象和原型
31.What is the result of this expression? (or multiple ones)
1 | function foo() { } |
考察函数名的只读性
函数名只读,不可修改,但是js里对其修改不报错,很奇怪。选C
32.What is the result of this expression? (or multiple ones)
1 | "1 2 3".replace(/\d/g, parseInt) |
考察replace
和parseInt
函数
replace函数中第二个参数为function函数,function函数的参数:
match
匹配的子串。(对应于上述的$&
。)p1, p2, ...
假如replace()
方法的第一个参数是一个RegExp 对象,则代表第n个括号匹配的字符串。(对应于上述的$1
,$2
等。)offset
匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是“abcd”,匹配到的子字符串是“bc”,那么这个参数将是1)string
被匹配的原字符串。
无括号,传入的是match, offset, string
,所以parseInt()
接收到的参数是[1, 0], [2, 2], [3, 4]
,得到1 NaN 3
,选D
33.What is the result of this expression? (or multiple ones)
1 | function f() {} |
考察函数的原型parent.name
为函数原型的名字,即原型链指向的其构造函数的原型对象的名字,返回空字符串,这个对象被定义了,但是不在这个作用域中。eval
对表达式进行求值。选C
34.What is the result of this expression? (or multiple ones)
1 | var lowerCaseOnly = /^[a-z]+$/; |
考察正则表达式对象的test()
方法
其参数为字符串类型,参数为空时,将其转化为字符undefined
,所以选C
35.What is the result of this expression? (or multiple ones)
1 | [,,,].join(", ") |
考察数组长度问题
js定义数组允许在数组末尾加逗号,所以这个数组的长度为3,所以选C
36.What is the result of this expression? (or multiple ones)
1 | var a = {class: "Animal", name: 'Fido'}; |
考察对象的class
浏览器兼容性问题
除了IE均返回"Animal"
,IE不能将保留字作为对象的属性
所以选D
37.What is the result of this expression? (or multiple ones)
1 | var a = new Date("epoch") |
考察Date
对象
创建Date
实例可使用new Date(dateString)
,dateString
需符合RFC2822格式,否则返回NaN
。chrome中测试返回invalid date
。
所以选D
38.What is the result of this expression? (or multiple ones)
1 | var a = Function.length, |
考察函数的长度Function.length
定义为1,而函数的prototype
的长度为0
所以选B
39.What is the result of this expression? (or multiple ones)
1 | var a = Date(0); |
考察Date对象
参见Date对象
1 | var a = Date(0); // 返回当前时间,为字符串格式 |
不考虑返回类型,a, b, c
也不会达到===
程度的相等,选B
40.What is the result of this expression? (or multiple ones)
1 | var min = Math.min(), max = Math.max() |
Math.min() // 无参数返回Inifinty
,Math.max() // 无参数返回-Inifinty
所以选择B
41.What is the result of this expression? (or multiple ones)
1 | function captureOne(re, str) { |
考察正则表达式对象的/g
使用和exec()
方法
当正则表达式使用g
标志时,可以多次执行exec
方法来查找同一个字符串中的成功匹配。当你这样做时,查找将从正则表达式的lastIndex
属性指定的位置开始。(test()
也会更新lastIndex
属性)。当调用exec()
的正则表达式对象具有修饰符g时,它将把当前正则表达式对象的lastIndex
属性设置为最近一次成功匹配的下一个位置,当同一个正则表达式第二次调用exec( )
,即使匹配的是不同的字符串,它会将从lastIndex
属性所指示的字符串处开始检索,如果exec()
没有发现任何匹配结果,它会将lastIndex
重置为0
。所以a1
执行完,numRe.lastIndex
为5, a3
无法匹配到,返回null
。
选择C
42.What is the result of this expression? (or multiple ones)
1 | var a = new Date("2014-03-19"), |
考察Date()
的获取属性的方法,参加Date对象。
用new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]])
方法构造Date
对象,月份从0开始,所以a, b
表示的是不同的日子。
所以选D
43.What is the result of this expression? (or multiple ones)
1 | if ('http://giftwrapped.com/picture.jpg'.match('.gif')) { |
考察String.prototype.match()
方法和if()
String.prototype.match()
方法未匹配到返回null
,匹配到返回Array
。对参数非正则对象对其进行隐式转换,'.gif'
中.
匹配除回车之外的任意字符。
所以选择A
44.What is the result of this expression? (or multiple ones)
1 | function foo(a) { |
考察变量提升和初始化
变量提升,但是若变量已经存在于作用域中,那么就会移除变量定义,但是不会移除变量初始化。
所以选B