第一题:下面代码输出的结果是什么
1 | ["1", "2", "3"].map(parseInt) |
答案: [1, NaN, NaN]
。
解析:
首先,这种写法,函数里面只写了一个 parseInt 就可以执行了。这个是函数式编程的一种概念,叫做 point free,具体的 point free 是个什么东西,还请您自行去 google 吧。这不是本章关注的重点。
在说说 parseInt
这个方法,他接收两个参数。第一个是要处理的字符串,第二个参数是转换的进制 radix
,取值是 2-36
的整数。10不是默认值,不同浏览器实现可能不同,虽然大部分浏览器都是将10作为默认值。
其次是数组的 map
方法,接受一个函数作为参数,这个参数函数接收三个参数:每一项的值、索引,数组本身。这里传入一个 parseInt
相当于是 parseInt
的第一个参数是数组的每一项,第二个参数是这一项的索引值。所以最终处理的是:
parseInt('1', 0)
parseInt('2', 1)
parseInt('3', 2)
这里有一个隐藏点,parseInt
第二个参数如果是 0,undefined,null,或者没有,按 10 处理 。
至于后面两项,来看这样一个例子
1 | parseInt('123', 2) |
最开始学习的时候你可能是这样学的,遇到字符串的第一个非数字停止,截取前面的,比如 100a
则截取前面的数字 100
,再比如 a100
截取 a
前面的,则为 ''
。现在再加一条,如果字符串中的数字大于 radix
,也停止,截取前面的。所以,这是按照二进制来处理的,字符串 123
的第一项是小于 2 的,后面两项都是大于 2 的,所以直接忽略,相当于是求 parseInt('1', 2)
的值。
至于超过 radix
范围的,则全部为 NaN
其次是第二项。没有取值为 1
的情况,则是 NaN
。
最后第三项。 3
的首位大于 2,直接截断,相当于 parseInt('', 2)
,则为 NaN
第二题:下面代码输出的结果是什么
1 | [typeof null, null instanceof Object] |
答案: ['object', false]
解析:
typeof null
—> ‘object’ 这是 ECMA-262规定的不多说。
object instanceof constructor
判断 constructor.prototype
是否在 object
的原型链上。基本数据类型(null,undefined,number,bool,string,symbol,bigInt)没有原型链
第三题:下面代码输出的结果是什么
1 | [ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ] |
答案:报错
解析:
数组的 reduce
方法 array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
前一个计算 $3^2=9$,在计算 $9^1=9$。最终是 9。
第二项是一个空数组, reduce
如果是一个空数组则会报错。reduceRight
也是一样的。
第四题:下面代码输出的结果是什么
1 | var val = 'smtg'; |
答案: Something
解析: +
操作的优先级高于三元表达式。
第五题:下面代码输出的结果是什么
1 | var name = 'World!'; |
答案: Goodbye Jack
解析:
var
存在变量提升,在 IIFE 中,先声明了变量 name
值是 undefined
。所以走了上面的 if
。如果将 var
变为 let
,那么因为不存在变量提升,所以会走 else
, name
取全局的 name = 'World'
第六题:下面代码输出的结果是什么
1 | var END = Math.pow(2, 53); |
答案:不是 100 也不是 101,而是其他,也不会报错。
解析:JavaScript中的数字使用了 IEEE 754 中规定的双精度浮点数数据类型,而这一数据类型能够安全存储 -Math.pow(2, 53) - 1
到 Math(2, 53) - 1
之间的数值(包含边界),上面的 END
超出了边界,这会是一个无限循环的。
第七题:下面代码输出的结果是什么
1 | var ary = [0,1,2]; |
答案: []
解析:缺少的元素不会调用 filter
。还有 map
不会处理没有初始化的 item
,返回 undefined
。
第八题:下面代码输出的结果是什么
1 | function showCase(value) { |
答案: 'Do not know!'
解析:switch 使用 ===
进行比较。 new String('A') == 'A'
但是 new String('A') !== 'A'
。那如果是 String('A')
呢,答案则是 Case A
。因为这个没有创建对象。使用 new
操作符才会创建对象。
第九题:下面代码输出的结果是什么
1 | Array.isArray( Array.prototype ) |
答案:true
解析: Array.prototype
是一个数组而不是一个对象。
第十题:下面代码输出的结果是什么
1 | var a = [0]; |
答案: false
解析: [0]
作为布尔值(或者说数组作为布尔值)的时候都认为是 true
。但是在进行相当判断的时候,会进行转换,调用 valueOf()
判断,如果无法比较,则继续调用 toString()
进行判断。
第十一题:下面代码输出的结果是什么
1 | 1 + - + + + - + 1 |
答案: 2
解析:相当于 1 + ( - + + + - + 1 )
的值。后面的计算: + 1 = 1
- 1 = -1
+ (-1) = -1
- (-1) = 1
。所以。两个减号相抵消,加好不用管。最终是 1 + 1
第十二题:下面代码输出的结果是什么
1 | 3.toString() |
答案: error, '3', error
解析: toString()
方法不能作用于整数。但是可以作用于小数。所以第一个报错。第二个呢, 3.
其实是一个小数,知道这个,那就没问题了。第三个,虽然是小数了,但是后面的两个点,语法都错了。
第十三题:下面代码输出的结果是什么
1 | function foo() { } |
答案: ['foo', 'foo']
解析:函数的 name
是只读的,返回函数的名字。
第十四题:下面代码输出的结果是什么
1 | var lowerCaseOnly = /^[a-z]+$/; |
答案: [true, true]
解析:正则调用 test
的时候会把测试的数据转换为字符串。所以上面的测试的是 'null'
和 'undefined'
第十五题:下面代码输出的结果是什么
1 | var min = Math.min(), max = Math.max() |
答案: false
解析: Math.min()
返回 +Infinity
而 Math.max()
返回 -Infinity
。所以,min > max
。So,terrible。我还以为最大的就是正无穷,最小就是负无穷呢。
第十六题:下面代码输出的结果是什么
1 | function foo(a) { |
答案: ['hello','bar']
解析: 在函数被声明与函数参数同名的变量,声明将会被移除,但是赋值不会被移除。所以 foo
中的声明被移除,是 hello
,而 bar
中的声明移除赋值保留 a = 'bye'
,是 bye
。
最后。掘金很少发文章了,大部分文章都放在自己的博客里面了。