专栏名称: java那些事
分享java开发中常用的技术,分享软件开发中各种新技术的应用方法。每天推送java技术相关或者互联网相关文章。关注“java那些事”,让自己做一个潮流的java技术人!《java程序员由笨鸟到菜鸟》系列文章火热更新中。
目录
相关文章推荐
芋道源码  ·  在公司整了这套系统架构,同事直呼666! ·  昨天  
芋道源码  ·  因为日报,架构师绩效被打C了! ·  5 天前  
芋道源码  ·  知乎热议:为什么很多程序员讨厌低代码? ·  6 天前  
芋道源码  ·  又来了一款神级搜索引擎,差别真的挺大! ·  6 天前  
芋道源码  ·  某大厂开始“捡漏”35+的人员了 ·  1 周前  
51好读  ›  专栏  ›  java那些事

网络语言,JavaScript 里那些奇怪的题目。你玩的转么?

java那些事  · 公众号  · Java  · 2017-02-28 16:32

正文


第1道:

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

解析: .map(callback(value, index, array)) 回调函数传入三个参数, parseInt(string, radix) 接收两个参数。所以map传递给parseInt的参数是这样的(parseInt忽略map传递的第三个参数)[1, 0],[2, 1],[3, 2],然乎parseInt()解析传过来的参数。

相当于执行以下语句:

parseInt('1', 0); 当radix为0时,默认为10进制,所以返回1parseInt('2', 1); 没有1进制,所以返回NaNparseInt('3', 2); 二进制中只有数字12,没有数字3,所以返回NaN

parseInt(string, radix) radix可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN

所以结果为 [1, NaN, NaN]


第2道:

[typeof null, null instanceof Object];

解析:typeof 返回一个表示类型的字符串,总是返回一个字符串。instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性,总是返回布尔值。

typeof null === 'object' typeof undefined === 'undefined'typeof Infinity === 'number'typeof NaN === 'number'

function c () {}function d () {}let o = new c(); o instanceof c; //true,因为Object.getPrototypeOf(o) === c.prototype)o instanceof Object; //true;因为Object.prototype.isPrototypeOf(o)返回true

所以结果为 [object, false]


第3道:

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

解析: arr.reduce(callback, [initialValue])

callback包含四个参数

  • accumulator上一次调用回调返回的值,或者是提供的初始值(initialValue)

  • currentValue 数组中正在处理的元素

  • currentIndex 数组中正在处理的的元素索引

  • array 调用reduce的数组

  • initialValue 其值用于第一次调用callback的第一个参数

另外如果数组为空并且没有提供initialValue,会抛出TypeError

第一个表达式等价于Math.pow(3, 2) => 9, Math.pow(9, 1) => 9

所以结果为 an error


第4道:

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

解析: 大多数人都会先看到三元运算符,然后输出结果Value is somethin

我也是这样/(ㄒoㄒ)/~~

这里主要是考虑了优先级。 + 的优先级是高于 ? 的 ,

所以执行顺序是

val === 'stmg' => true'Value is' + true => 'Value is true''Value is true ' ? 'Something' : 'Nothing' => 'Something'

所以结果为 'Something'


第5题:

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

解析:主要考虑变量声明提升,本题相当于把name声明到顶部但是未定义。

这里扩充一下函数提升

dohois(); //"提升了"donothois(); //TypeError: undefined is not a function//函数声明提升function dohois () {    console.log("提升了"); }//函数表达式不提升var donothois = function () {    console.log("没有提升"); }

所以结果为 Goodbye Jack


第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);

解析:JS里Math.pow(2, 53)是可以表示的最大值,最大值加1还是最大值。发生的情况是这样的 : Math.pow(2, 53) == Math.pow(2, 53) + 1 ,所以永远不可能大于Math.pow(2, 53)。

console.log(Infinity); //Infinityconsole.log(Infinity + 1); //Infinity

所以结果是 无限循环


第7道:

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

解析:首先需要理解稀疏数组和密集数组

创建一个稀疏数组,遍历稀疏数组时,会发现这个数组并没有元素,js会跳过这些坑。

//第一种情况var a = new Array(3); console.log(a); //[, , ,]//第二种情况var arr = []; arr[0] = 1; arr[100] = 100; a.map(function (x, i) {return i}); //[, , ,]

创建一个密集数组,可以遍历到这些数组元素

var a = Array.apply(null, Array(3));console.log(a); //[undefined, undefined, undefined]a.map(function (x, i) {return i}); //[0, 1, 2]

这道题目里的数组是一个稀疏数组,不会遍历到(从索引3-9)“坑”,这些索引都不存在数组中,会直接跳过这些坑。所以永远筛选不到等于undefined的值。

所以结果为 []


第8道:

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

解析: js的浮点数运算,不能精确的表达小数。什么时候会精确呢,都不知道( ╯□╰ )。

所以结果为 [true, false]


第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是严格比较。

这里要考虑字符串。

var s_prim = 'foo';var s_obj = new String(s_prim);console.log(typeof s_prim); //"String"console.log(typeof s_obj); //"object"

所以不可能匹配到case,所以结果为 Do not know


第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!');    } } showCase2(String('A'));

解析:和第九题类似,但是注意此时 typeof String('A') === 'string'

所以结果为 Case A


第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);

解析:主要在于 -9 % 2 == -1 保留正负号。 Infinity % 2 得到的是NaN,但是注意NaN与所有值都不相等包括本身。

所以结果为 [true, true, true, false, false]


第12题

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

解析:和第一题考察的概念一样。2进制里没有数字3,radix为0时时10进制

所以结果为 [3, NaN, 3]


第13题

Array.isArray( Array.prototype )

解析:Array.prototype本身是一个数组,这只能牢牢记住了~

所以结果为 [true]


第14题

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

解析:所有对象都是true,但是当执行a == true时会进行隐式转换。

所以结果为 false


第15题

[] == []

解析:2个引用的是同一个对象、函数、数组,则它们相等,如果引用的不是同一个对象、函数、数组,则不相同,即使这2个对象、函数、数组可以转换成完全相等的原始值。

所以结果为 false


第16题

'5' + 3'5' - 3

解析:考察字符串拼接


第17题

1 + - + + + - + 1

解析:从后面开始计算,首先得到一个正数(+1),然后往前都是符号的改变得到(-1 -1 -1 -1 +1 ),等于1+(+1)

所以结果为 2


第18题

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

解析: 稀疏数组,会跳过这些未被赋值的“坑”。所以只有ary[0]能被遍历到

所以结果为 [1, undefined × 2]


第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)

解析:

so changing the variables changes arguments and changing arguments changes the local variables even when they are not in the same scope.

改变变量改变了arguments,改变argumnets也改变了本地变量,即时他们不在一个作用域。

arguments就是传进来的参数组成的类数组。所以sidEffecting([a, b, c]),就知道a和c都为10,b为1。

ヽ(*。>Д

但是当函数参数涉及到 any rest parameters, any default parameters(默认参数) or any destructured parameters 的时候, 这个 arguments 就不在是一个 mapped arguments object 了

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

所以结果为 21


第20题

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

解析:由于JS能表示整数范围为-2^53~2^53,这里的a已经超过了2^53,与第六题类似,最大值加上一个数还是最大值。所以还是a

所以结果为 a


第21题

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

解析:最后会返回这个调用者(this),x执行的时候的上下文是全局,所以返回的是window。

所以结果为 window


第22题

Number.MIN_VALUE > 0

解析:Number.MIN_VALUE 属性表示在 JavaScript 中所能表示的最小的正值。MIN_VALUE 属性是 JavaScript 里最接近 0 的正值,而不是最小的负值。


推荐程序员必备微信号 


程序员内参
微信号:

programmer0001



推荐理由:
在这里,我们分享程序员相关技术,职场生活,行业热点资讯。不定期还会分享IT趣文和趣图。这里属于我们程序员自己的生活,工作和娱乐空间。


 ▼长按下方↓↓↓二维码识别关注