面試官總結:44個 Javascript 變態題解析(上)

編程語言 JavaScript Chrome Numbers 孝道的重要性 孝道的重要性 2017-08-26

當初筆者做這套題的時候不僅懷疑智商, 連人生都開始懷疑了....

不過, 對於基礎知識的理解是深入編程的前提. 讓我們一起來看看這些變態題到底變態不變態吧!

第1題

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

知識點:

  • Array/map

  • Number/parseInt

  • Global_Objects/parseInt

  • JavaScript parseInt

首先, map接受兩個參數, 一個回調函數 callback, 一個回調函數的this值

其中回調函數接受三個參數 currentValue, index, arrary;

而題目中, map只傳入了回調函數--parseInt.

其次, parseInt 只接受兩個兩個參數 string, radix(基數).

在沒有指定基數,或者基數為 0 的情況下,JavaScript 作如下處理:

  • 如果字符串 string 以"0x"或者"0X"開頭, 則基數是16 (16進制).

  • 如果字符串 string 以"0"開頭, 基數是8(八進制)或者10(十進制),那麼具體是哪個基數由實現環境決- 定。ECMAScript 5 規定使用10,但是並不是所有的瀏覽器都遵循這個規定。因此,永遠都要明確給出radix參數的值。

  • 如果字符串 string 以其它任何值開頭,則基數是10 (十進制)。

所以本題即問

parseInt('1', 0);

首先後兩者參數不合法.

所以答案是 [1, NaN, NaN]

第2題

[typeof null, null instanceof Object]

兩個知識點:

  • Operators/typeof

  • Operators/instanceof

  • Operators/instanceof(中)

typeof 返回一個表示類型的字符串.

instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上.

這個題可以直接看鏈接... 因為 typeof null === 'object' 自語言之初就是這樣....

typeof 的結果請看下錶:

type result

所以答案 [object, false]

第3題

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

知識點:

  • Array/Reduce

arr.reduce(callback[, initialValue])

reduce接受兩個參數, 一個回調, 一個初始值.

回調函數接受四個參數 previousValue, currentValue, currentIndex, array

需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.

所以第二個表達式會報異常. 第一個表達式等價於 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9

答案 an error

第4題

var val = 'smtg';

兩個知識點:

  • Operators/Operator_Precedence

  • Operators/Conditional_Operator

簡而言之 + 的優先級 大於 ?

所以原題等價於 'Value is true' ? 'Somthing' : 'Nonthing' 而不是 'Value is' + (true ? 'Something' : 'Nonthing')

答案 'Something'

第5題

var name = 'World!';

這個相對簡單, 一個知識點:

  • Hoisting

在 JavaScript中, functions 和 variables 會被提升。變量提升是JavaScript將聲明移至作用域 scope (全局域或者當前函數作用域) 頂部的行為。

這個題目相當於

var name = 'World!';

所以答案是 'Goodbye Jack'

第6題

var END = Math.pow(2, 53);

一個知識點:

  • Infinity

在 JS 裡, Math.pow(2, 53) == 9007199254740992 是可以表示的最大值. 最大值加一還是最大值. 所以循環不會停.

補充: @jelly7723

js中可以表示的最大整數不是2的53次方,而是1.7976931348623157e+308。

2的53次方不是js能表示的最大整數而應該是能正確計算且不失精度的最大整數,可以參見js權威指南。

9007199254740992 +1還是 9007199254740992 ,這就是因為精度問題,如果 9007199254740992 +11或者 9007199254740992 +111的話,值是會發生改變的,只是這時候計算的結果不是正確的值,就是因為精度丟失的問題。

第7題

var ary = [0,1,2];

答案是 []

看一篇文章理解稀疏數組

  • 譯 JavaScript中的稀疏數組與密集數組

  • Array/filter

我們來看一下 Array.prototype.filter 的 polyfill:

if (!Array.prototype.filter) {

我們看到在迭代這個數組的時候, 首先檢查了這個索引值是不是數組的一個屬性, 那麼我們測試一下.

0 in ary; => true

也就是說 從 3 - 9 都是沒有初始化的'坑'!, 這些索引並不存在與數組中. 在 array 的函數調用的時候是會跳過這些'坑'的.

第8題

var two = 0.2
  • JavaScript的設計缺陷?浮點運算:0.1 + 0.2 != 0.3

IEEE 754標準中的浮點數並不能精確地表達小數

那什麼時候精準, 什麼時候不經準呢? 筆者也不知道...

答案 [true, false]

第9題

function showCase(value) {

兩個知識點:

  • Statements/switch

  • String

switch 是嚴格比較, String 實例和 字符串不一樣.

var s_prim = 'foo';

答案是 'Do not know!'

第10題

function showCase2(value) {

解釋:

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

一個知識點

  • Arithmetic_Operators#Remainder

此題等價於

7 % 2 => 1

需要注意的是 餘數的正負號隨第一個操作數.

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

第12題

parseInt(3, 8)

第一個題講過了, 答案 3, NaN, 3

第13題

Array.isArray( Array.prototype )

一個知識點:

  • Array/prototype

一個鮮為人知的實事: Array.prototype => [];

---> 對JS原型的一些思考 by renaesop

答案: true

第14題

var a = [0];
  • JavaScript-Equality-Table

  • 更新通過一張簡單的圖,讓你徹底地、永久地搞懂JS的==運算 非常不錯的一篇文章!

解析:

  • Boolean([0]) === true

  • [0] == true

  • true 轉換為數字 => 1

  • [0] 轉化為數字失敗, 轉化為字符串 '0', 轉化成數字 => 0

  • 0 !== 1

答案: false

第15題

[]==[]

[] 是Object, 兩個 Object 不相等

答案是 false

第16題

'5' + 3

兩個知識點:

  • Arithmetic_Operators#Addition

  • Arithmetic_Operators#Subtraction

+ 用來表示兩個數的和或者字符串拼接, -表示兩數之差.

請看例子, 體會區別:

> '5' + 3

也就是說 - 會盡可能的將兩個操作數變成數字, 而 + 如果兩邊不都是數字, 那麼就是字符串拼接.

答案是 '53', 2

第17題

1 + - + + + - + 1

這裡應該是(倒著看)

1 + (a) => 2

所以答案 2

第18題

var ary = Array(3);

稀疏數組. 同第7題.

題目中的數組其實是一個長度為3, 但是沒有內容的數組, array 上的操作會跳過這些未初始化的'坑'.

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

這裡貼上 Array.prototype.map 的 polyfill.

Array.prototype.map = function(callback, thisArg) {

第19題

function sidEffecting(ary) {

這是一個大坑, 尤其是涉及到 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) {

答案是 12 !!!!

請讀者細細體會!!

第20題

var a = 111111111111111110000,

答案還是 111111111111111110000. 解釋是 Lack of precision for numbers in JavaScript affects both small and big numbers. 但是筆者不是很明白................ 請讀者賜教!

第21題

var x = [].reverse;

這個題有意思!

知識點:

  • 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.

補充:

@stellar91 這個筆者實踐了一下 發現 firefox 是 window, chrome 報錯 VM190:2 Uncaught TypeError: Array.prototype.reverse called on null or undefined(…) 可能是實現不同, 在 chrome 中應該是對調用者做了檢查.

答案是 window

第22題

Number.MIN_VALUE > 0

true

@10081677wc

MIN_VALUE 屬性是 JavaScript 中可表示的最小的數(接近 0 ,但不是負數),它的近似值為 5 x 10-324。

今天先到這裡, 下次我們來看後22個題!

最後在對各位剛剛入門前端的程序員提點建議。

對於剛剛參加工作的同學來說,思考比做事更重要。如果你為了業務而業務,不停的去堆積,只能說過些年你還是如此。去好好的想一想,編程到底是在做什麼?

如果你現在還準備去學習前端 ,那我只能說你的視野都被狗吃了。至少你可以通過社區來了解前端的發展動態,去了解出現了哪些新的框架,更新了哪些新的Api或者屬性。未來一段時間內,國內或者國際廠商會使用哪些技術等等。

分享之前我還是要推薦下我自己的前端學習群:180442230,不管你是小白還是大牛,小編我都挺歡迎,不定期分享乾貨,包括我自己整理的一份2017最新的前端資料和零基礎入門教程,送給大家,歡迎初學和進階中的小夥伴

相關推薦

推薦中...