Detailed introduction to the analysis of 44 JavaScript abnormal questions

黄舟
Release: 2017-03-07 14:33:59
Original
1338 people have browsed it

When I did this set of questions, I not only doubted my IQ, but also my life...

However, the understanding of basic knowledge is the prerequisite for in-depth programming. Let us Let’s see if these abnormal questions are abnormal or not!

Question 1

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

Knowledge points:

  • Array/map

  • Number/parseInt

  • JavaScript parseInt

First, map accepts two parameters, a callback function callback , the this value of a callback function

The callback function accepts three parameters currentValue, index, array;

And in the question, map only passes in the callback function –parseInt.

Secondly, parseInt only accepts two parameters string, radix (radix).

Optional. Represents the base of the number to be parsed. The value is between 2 ~ 36.

If this parameter is omitted or its value is 0, the number will be parsed in base 10. If it starts with "0x" or "0X" it will be base 16.

If the parameter is less than 2 or greater than 36, parseInt() will return NaN.

So this question is

parseInt('1', 0); parseInt('2', 1); parseInt('3', 2);
Copy after login

First of all, the latter two parameters are illegal.

So the answer is[1, NaN, NaN]

Question 2

[typeof null, null instanceof Object]
Copy after login

Two knowledge points:

  • Operators/typeof

  • ##Operators/ instanceof

  • Operators/instanceof(中)

typeof returns a string representing the type.

The instanceof operator is used To detect whether constructor.prototype exists on the prototype chain of parameter object.

You can directly see the link for this question... Because

typeof null === 'object'This has been the case since the beginning of the language... .

typeof results please see the table below:

type result Undefined "undefined" Null "object" Boolean "boolean" Number "number" String "string" Symbol "symbol" Host object Implementation-dependent Function "function" Object "object"
Copy after login

So the answer

[object, false]

Question 3

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

Knowledge points:

  • Array/Reduce

##arr.reduce(callback[, initialValue])

reduce accepts two parameters, a callback and an initial value.

The callback function accepts four parameters

previousValue, currentValue, currentIndex, array

Things to note Yes

If the array is empty and no initialValue was provided, TypeError would be thrown.

So the second expression will throw an exception. The first expression is equivalent to

Math.pow(3, 2) => 9; Math.pow(9, 1) =>9

Answer

an error

4 questions

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

Two knowledge points:

    Operators/Operator_Precedence
  • Operators/Conditional_Operator
  • In short, the priority of
+

is greater than?So the original question is equivalent to

'Value is true' ? ' Somthing' : 'Nonthing'

instead of'Value is' + (true ? 'Something' : 'Nonthing')Answer

'Something'

Question 5

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

This is relatively simple, a knowledge point:

    Hoisting
  • ##In JavaScript , functions and variables will be promoted. Variable hoisting is JavaScript's behavior of moving declarations to the top of the scope (either the global scope or the current function scope).
This question is equivalent to

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

so the answer is

'Goodbye Jack'

Question 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);
Copy after login

A knowledge point:

Infinity
  • In JS, Math.pow(2, 53) == 9007199254740992 is the maximum value that can be represented. The maximum value plus one is still the maximum value. So the loop will not stop.

Additional: @jelly7723

The largest integer that can be represented in js is not 2 to the 53rd power. But 1.7976931348623157e+308. The 53rd power of

2 is not the largest integer that js can represent but should be the largest integer that can be calculated correctly without losing accuracy. Please refer to the js authoritative guide.
9007199254740992 +1 or 9007199254740992, this is because of the accuracy problem. If 9007199254740992 +11 or 9007199254740992 +111, the value will change, but the calculated result at this time is not the correct value, because of the loss of accuracy.



Question 7

var ary = [0,1,2]; ary[10] = 10; ary.filter(function(x) { return x === undefined;});
Copy after login
The answer is

[]

Read an article to understand sparse arrays

Translation Sparse arrays and dense arrays in JavaScript
  • Array/filter
  • Let’s take a look at Array.prototype.filter polyfill:
  • if (!Array.prototype.filter) { Array.prototype.filter = function(fun/*, thisArg*/) { 'use strict'; if (this === void 0 || this === null) { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; if (typeof fun !== 'function') { throw new TypeError(); } var res = []; var thisArg = arguments.length >= 2 ? arguments[1] : void 0; for (var i = 0; i < len; i++) { if (i in t) { // 注意这里!!! var val = t[i]; if (fun.call(thisArg, val, i, t)) { res.push(val); } } } return res; }; }
    Copy after login
We see that when iterating this array, we first check whether the index value is an attribute of the array, then let’s test it.

0 in ary; => true 3 in ary; => false 10 in ary; => true
Copy after login

That is to say, from 3 – 9 are all uninitialized 'holes'!, these indexes do not exist in the array. These 'holes' will be skipped when the array function is called.

Question 8

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

Design flaw in JavaScript? Floating point arithmetic: 0.1 + 0.2 != 0.3
  • ##Floating point numbers
  • in the IEEE 754 standard are not Unable to express decimals accurately

那什么时候精准, 什么时候不经准呢? 笔者也不知道…

答案[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'));
Copy after login

两个知识点:

  • Statements/switch

  • String

switch 是严格比较, String 实例和 字符串不一样.

var s_prim = 'foo'; var s_obj = new String(s_prim); console.log(typeof s_prim); // "string" console.log(typeof s_obj); // "object" console.log(s_prim === s_obj); // false
Copy after login

答案是'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'));
Copy after login

解释:

String(x) does not create an object but does return a string, i.e. typeof String(1) === "string"

还是刚才的知识点, 只不过 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);
Copy after login

一个知识点

  • Arithmetic_Operators#Remainder

此题等价于

7 % 2 => 1 4 % 2 => 0 '13' % 2 => 1 -9 % % 2 => -1 Infinity % 2 => NaN
Copy after login

需要注意的是 余数的正负号随第一个操作数.

答案[true, true, true, false, false]

第12题

parseInt(3, 8) parseInt(3, 2) parseInt(3, 0)
Copy after login

第一个题讲过了, 答案3, NaN, 3

第13题

Array.isArray( Array.prototype )
Copy after login

一个知识点:

  • Array/prototype

一个鲜为人知的实事:Array.prototype => [];

答案:true

第14题

var a = [0]; if ([0]) { console.log(a == true); } else { console.log("wut"); }
Copy after login
  • JavaScript-Equality-Table

答案:false

第15题

[]==[]
Copy after login

==是万恶之源, 看上图

答案是false

第16题

'5' + 3 '5' - 3
Copy after login

两个知识点:

  • Arithmetic_Operators#Addition

  • Arithmetic_Operators#Subtraction

+用来表示两个数的和或者字符串拼接,-表示两数之差.

请看例子, 体会区别:

> '5' + 3 '53' > 5 + '3' '53' > 5 - '3' 2 > '5' - 3 2 > '5' - '3' 2
Copy after login

也就是说-会尽可能的将两个操作数变成数字, 而+如果两边不都是数字, 那么就是字符串拼接.

答案是'53', 2

第17题

1 + - + + + - + 1
Copy after login

这里应该是(倒着看)

1 + (a) => 2 a = - (b) => 1 b = + (c) => -1 c = + (d) => -1 d = + (e) => -1 e = + (f) => -1 f = - (g) => -1 g = + 1 => 1
Copy after login

所以答案2

第18题

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

稀疏数组. 同第7题.

题目中的数组其实是一个长度为3, 但是没有内容的数组, array 上的操作会跳过这些未初始化的’坑’.

所以答案是["1", undefined × 2]

这里贴上 Array.prototype.map 的 polyfill.

Array.prototype.map = function(callback, thisArg) { var T, A, k; if (this == null) { throw new TypeError(' this is null or not defined'); } var O = Object(this); var len = O.length >>> 0; if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } if (arguments.length > 1) { T = thisArg; } A = new Array(len); k = 0; while (k < len) { var kValue, mappedValue; if (k in O) { kValue = O[k]; mappedValue = callback.call(T, kValue, k, O); A[k] = mappedValue; } k++; } return A; };
Copy after login

第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)
Copy after login

这是一个大坑, 尤其是涉及到 ES6语法的时候

知识点:

  • Functions/arguments

首先The arguments object is an Array-like object corresponding to the arguments passed to a function.

也就是说arguments是一个object, c 就是 arguments[2], 所以对于 c 的修改就是对 arguments[2] 的修改.

所以答案是21.

然而!!!!!!

当函数参数涉及到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)
Copy after login

答案是12!!!!

请读者细细体会!!

第20题

var a = 111111111111111110000, b = 1111; a + b;
Copy after login

答案还是111111111111111110000. 解释是Lack of precision for numbers in JavaScript affects both small and big numbers.但是笔者不是很明白……………. 请读者赐教!

第21题

var x = [].reverse; x();
Copy after login

这个题有意思!

知识点:

  • Array/reverse

The reverse method transposes the elements of the calling array object in place, mutating the array, and returning a reference to the array.

也就是说 最后会返回这个调用者(this), 可是 x 执行的时候是上下文是全局. 那么最后返回的是window.

答案是window

第22题

Number.MIN_VALUE > 0
Copy after login

true

第23题

[1 < 2 < 3, 3 < 2 < 1]
Copy after login

这个题也还可以.

这个题会让人误以为是2 > 1 && 2 < 3其实不是的.

这个题等价于

1 < 2 => true; true < 3 => 1 < 3 => true; 3 < 2 => false; false < 1 => 0 < 1 => true;
Copy after login

答案是[true, true]

第24题

// the most classic wtf 2 == [[[2]]]
Copy after login

这个题我是猜的. 我猜的true, 至于为什么…..

both objects get converted to strings and in both cases the resulting string is "2"我不能信服…

第25题

3.toString() 3..toString() 3...toString()
Copy after login

这个题也挺逗, 我做对了Detailed introduction to the analysis of 44 JavaScript abnormal questions答案是error, '3', error

你如果换一个写法就更费解了

var a = 3; a.toString()
Copy after login

这个答案就是'3';

为啥呢?

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

第26题

(function(){ var x = y = 1; })(); console.log(y); console.log(x);
Copy after login

答案是1, error

y 被赋值到全局. x 是局部变量. 所以打印 x 的时候会报ReferenceError

第27题

var a = /123/, b = /123/; a == b a === b
Copy after login

即使正则的字面量一致, 他们也不相等.

答案false, false

第28题

var a = [1, 2, 3], b = [1, 2, 3], c = [1, 2, 4] a == b a === b a > c a < c
Copy after login

字面量相等的数组也不相等.

数组在比较大小的时候按照字典序比较

答案false, false, false, true

第29题

var a = {}, b = Object.prototype; [a.prototype === b, Object.getPrototypeOf(a) === b]
Copy after login

知识点:

  • Object/getPrototypeOf

只有 Function 拥有一个 prototype 的属性. 所以a.prototypeundefined.

Object.getPrototypeOf(obj)返回一个具体对象的原型(该对象的内部[[prototype]]值)

答案false, true

第30题

function f() {} var a = f.prototype, b = Object.getPrototypeOf(f); a === b
Copy after login

f.prototype is the object that will become the parent of any objects created with new f while Object.getPrototypeOf returns the parent in the inheritance hierarchy.

f.prototype 是使用使用 new 创建的 f 实例的原型. 而 Object.getPrototypeOf 是 f 函数的原型.

请看:

a === Object.getPrototypeOf(new f()) // true b === Function.prototype // true
Copy after login

答案false

第31题

function foo() { } var oldName = foo.name; foo.name = "bar"; [oldName, foo.name]
Copy after login

答案['foo', 'foo']

知识点:

  • Function/name

因为函数的名字不可变.

第32题

"1 2 3".replace(/\d/g, parseInt)
Copy after login

知识点:

  • String/replace#Specifying_a_function_as_a_parameter

str.replace(regexp|substr, newSubStr|function)

如果replace函数传入的第二个参数是函数, 那么这个函数将接受如下参数

  • match 首先是匹配的字符串

  • p1, p2 …. 然后是正则的分组

  • offset match 匹配的index

  • string 整个字符串

由于题目中的正则没有分组, 所以等价于问

parseInt('1', 0) parseInt('2', 2) parseInt('3', 4)
Copy after login

答案:1, NaN, 3

第33题

function f() {} var parent = Object.getPrototypeOf(f); f.name // ? parent.name // ? typeof eval(f.name) // ? typeof eval(parent.name) // ?
Copy after login

先说以下答案'f', 'Empty', 'function', error这个答案并不重要…..

这里第一小问和第三小问很简单不解释了.

第二小问笔者在自己的浏览器测试的时候是'', 第四问是'undefined'

所以应该是平台相关的. 这里明白parent === Function.prototype就好了.

第34题

var lowerCaseOnly = /^[a-z]+$/; [lowerCaseOnly.test(null), lowerCaseOnly.test()]
Copy after login

知识点:

  • RegExp/test

这里 test 函数会将参数转为字符串.'nul','undefined'自然都是全小写了

答案:true, true

第35题

[,,,].join(", ")
Copy after login

[,,,] => [undefined × 3]

因为javascript 在定义数组的时候允许最后一个元素后跟一个,, 所以这是个长度为三的稀疏数组(这是长度为三, 并没有 0, 1, 2三个属性哦)

答案:", , "

第36题

var a = {class: "Animal", name: 'Fido'}; a.class
Copy after login

这个题比较流氓.. 因为是浏览器相关,class是个保留字(现在是个关键字了)

所以答案不重要, 重要的是自己在取属性名称的时候尽量避免保留字. 如果使用的话请加引号a['class']

第37题

var a = new Date("epoch")
Copy after login

知识点:

  • Date

  • Date/parse

简单来说, 如果调用 Date 的构造函数传入一个字符串的话需要符合规范, 即满足 Date.parse 的条件.

另外需要注意的是 如果格式错误 构造函数返回的仍是一个Date 的实例Invalid Date.

答案Invalid Date

第38题

var a = Function.length, b = new Function().length a === b
Copy after login

我们知道一个function(Function 的实例)的length属性就是函数签名的参数个数, 所以 b.length == 0.

另外 Function.length 定义为1……

所以不相等…….答案false

第39题

var a = Date(0); var b = new Date(0); var c = new Date(); [a === b, b === c, a === c]
Copy after login

还是关于Date 的题, 需要注意的是

  • 如果不传参数等价于当前时间.

  • 如果是函数调用 返回一个字符串.

答案false, false, false

第40题

var min = Math.min(), max = Math.max() min < max
Copy after login

知识点:

  • Math/min

  • Math/max

有趣的是, Math.min 不传参数返回Infinity, Math.max 不传参数返回-Infinity

答案:false

第41题

function captureOne(re, str) { var match = re.exec(str); return match && match[1]; } var numRe = /num=(\d+)/ig, wordRe = /word=(\w+)/i, a1 = captureOne(numRe, "num=1"), a2 = captureOne(wordRe, "word=1"), a3 = captureOne(numRe, "NUM=2"), a4 = captureOne(wordRe, "WORD=2"); [a1 === a2, a3 === a4]
Copy after login

知识点:

  • RegExp/exec

通俗的讲

因为第一个正则有一个 g 选项 它会‘记忆’他所匹配的内容, 等匹配后他会从上次匹配的索引继续, 而第二个正则不会

举个例子

var myRe = /ab*/g; var str = 'abbcdefabh'; var myArray; while ((myArray = myRe.exec(str)) !== null) { var msg = 'Found ' + myArray[0] + '. '; msg += 'Next match starts at ' + myRe.lastIndex; console.log(msg); } // Found abb. Next match starts at 3 // Found ab. Next match starts at 9
Copy after login

所以 a1 = ’1′; a2 = ’1′; a3 = null; a4 = ’2′

答案[true, false]

第42题

var a = new Date("2014-03-19"), b = new Date(2014, 03, 19); [a.getDay() === b.getDay(), a.getMonth() === b.getMonth()]
Copy after login

这个….

JavaScript inherits 40 years old design from C: days are 1-indexed in C’s struct tm, but months are 0 indexed. In addition to that, getDay returns the 0-indexed day of the week, to get the 1-indexed day of the month you have to use getDate, which doesn’t return a Date object.

a.getDay() 3 b.getDay() 6 a.getMonth() 2 b.getMonth() 3
Copy after login

都是套路!

答案[false, false]

第43题

if ('http://giftwrapped.com/picture.jpg'.match('.gif')) { 'a gif file' } else { 'not a gif file' }
Copy after login

知识点:

  • String/match

String.prototype.match 接受一个正则, 如果不是, 按照new RegExp(obj)转化. 所以.并不会转义
那么/gif就匹配了 /.gif/

答案:'a gif file'

第44题

function foo(a) { var a; return a; } function bar(a) { var a = 'bye'; return a; } [foo('hello'), bar('hello')]
Copy after login

在两个函数里, a作为参数其实已经声明了, 所以var a; var a = 'bye'其实就是a; a ='bye'

所以答案'hello', 'bye'

以上就是详细介绍44 个 JavaScript 变态题解析的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!