做者:Dmitri Pavlutinjavascript
譯者:前端小智html
來源:dmitripavlutin前端
阿(a)裏(li)雲(yun)服務器很便宜火爆,今年比去年便宜,10.24~11.11購買是1年86元,3年229元,能夠點我時行參與java
爲了保證的可讀性,本文采用意譯而非直譯。git
在 JS 面試中,常常會看到一些簡單而又沙雕的題目,這些題目包含一些陷阱,但這些在咱們規範的編碼下或者業務中基本不會出現。 有些面試官就是這樣,不專一於制定代碼的標準和規範上,卻用不規範的代碼去檢驗別人是否細心。github
這魔幻的世界就是一個攀比優越感的,我能考你,我就是比你優越,真實。面試
來看看這 7 個沙雕題目是哪些。數組
面試官問瀏覽器
在下面的代碼中 typeof a
和 typeof b
結果各自是什麼?(沙雕)服務器
function foo() {
let a = b = 0;
a++;
return a;
}
foo();
typeof a; // => ???
typeof b; // => ???
複製代碼
答案
這個代碼的重點在第二行
:let a = b = 0
。這個語句聲明瞭一個局部變量 a
,可是它也聲明瞭一個全局變量b
。
在 foo()
做用域或全局做用域中都沒有聲明變量 b
。所以 JS 引薦將b = 0
表達式解釋爲 window.b = 0
。
以下圖所示,函數 foo
中的 i
都是一個偶然建立的全局變量:
一樣,在我們的問題中,b
是一個偶然建立的全局變量。在瀏覽器中,上面的代碼至關於以下:
function foo() {
let a;
window.b = 0;
a = window.b;
a++;
return a;
}
foo();
typeof a; // => 'undefined'
typeof window.b; // => 'number'
複製代碼
typeof a
是 'undefined'
。變量 a
僅在 foo()
做用域中聲明,在外部做用域內不可用。
typeof b
結果是 'number'
。b
是一個值爲 0
的全局變量
面試官問
clothes[0]
的值是什麼?(沙雕)
const clothes = ['jacket', 't-shirt'];
clothes.length = 0;
clothes[0]; // => ???
複製代碼
答案
數組對象的 length
屬性具備一些特殊的行爲:
減小
length
屬性的值的反作用是刪除本身的
數組元素,這些元素的數組索引位於新舊長度值之間。
因爲 length
屬性行爲,當 JS 執行 clothes.length = 0
時,刪除全部的 clothes
項。 因此 clothes[0]
的值爲 undefined
,由於 clothes
數組已被清空。
面試官問
下面代碼中 numbers 數組的內容是什麼? 注意 for()
後加了一個分號(;
),真是沙雕。
const length = 4;
const numbers = [];
for (var i = 0; i < length; i++);{
numbers.push(i + 1);
}
numbers; // => ???
複製代碼
答案
上面代碼中 for()
後加了一個分號(;
) ,加上分號,JS 會認爲該語句結束,因此 for 循環執行了4次空語句,當退出循環的時候,此時的 i 值爲 4。
而後執行 { numbers.push(i + 1); }
,因此最終 numbers
內容只有一個數字 5
。
上面的代碼至關於下面的代碼
const length = 4;
const numbers = [];
var i;
for (i = 0; i < length; i++) {
// does nothing
}
{
// a simple block
numbers.push(i + 1);
}
numbers; // => [5]
複製代碼
用不規範的代碼去檢驗別人是否細心,我以爲很沙雕。
面試官問
arrayFromValue()
返回什麼值?(沙雕)
function arrayFromValue(items) {
return
[items];
}
arrayFromValue(10); // => ???
複製代碼
答案
這裏須要注意的 return
和 [items]
之間已經換行了,JS 會在換行之間自動插入分號。因此上面等價下面的代碼:
function arrayFromValue(items) {
return;
[items];
}
arrayFromValue(10); // => undefined
複製代碼
return;
在函數內部使該函數返回 undefined
,因此 arrayFromValue(10)
的值爲 undefined
。
面試官問
下面的代碼執行結果是什麼?(能不能換個題)
let i;
for (i = 0; i < 3; i++) {
const log = () => {
console.log(i);
}
setTimeout(log, 100);
}
複製代碼
答案
當你對 JS 基礎不是很瞭解的時候,很容易給出 0, 1, 2
的答案,我第一次在學校遇到這個題目也是這個答案。
執行這段代碼的過程有兩個階段。
階段1
for()
迭代 3
次。在每次迭代時,都會建立一個新函數 log()
,該函數將捕獲變量 i
。而後,setTimout()
調度 log()
的執行。
當 for()
循環完成時,變量 i
的值爲 3
。
log()
是一個捕獲變量 i
的閉包,該變量在 for()
循環的外部做用域中定義。重要的是要了解閉包在詞法上捕獲了變量 i
。
階段 2
第二階段發生在 100
毫秒以後
setTimeout()調用 3
個 log()
回調。log()
讀取變量 i
的當前值,即 3
。
這就是爲何控制檯輸出爲 3
, 3
和 3
的緣由
面試官問
下面的代碼輸出是什麼? (能不能換個題)
0.1 + 0.2 === 0.3 // => ???
複製代碼
答案
首先,來看一下 0.1 + 0.2
的值
0.1 + 0.2; // => 0.30000000000000004
複製代碼
0.1
和 0.2
的和不等於 0.3
,但略高於 0.3
。
因爲以二進制方式對浮點數進行編碼,所以像浮點數相加之類的操做會產生舍入偏差。
所以, 0.1 + 0.2 === 0.3
是 false
。
面試官問
若是在聲明以前訪問 myVar
和 myConst
會發生什麼?(能不能換個題)
myVar; // => ???
myConst; // => ???
var myVar = 'value';
const myConst = 3.14;
複製代碼
答案
提高和時間死區是影響 JS 變量生命週期的兩個重要概念。
在聲明以前訪問 myVar
的結果是 undefined
,由於使用 var 聲明的變量會被提高且值爲 undefined
。
可是,在聲明行以前訪問 myConst
會引起 ReferenceError
。在代碼行 const myConst = 3.14
以前,const
變量處於臨時死區。
你有沒有感受上面的問題,有些是對面試毫無用處,特別是第3道題目。可是,仍是有一小部分的面試中會被問到。
固然,雖然都說是沙雕題目,但這些是能夠評估你是否精通 JS,仍是有咱們學習的知識的。
在面試中,你還遇到哪些像這樣的題目,歡迎留言討論。
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
原文:dmitripavlutin.com/simple-but-…
阿里雲最近在作活動,低至2折,有興趣能夠看看:promotion.aliyun.com/ntms/yunpar…
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
由於篇幅的限制,今天的分享只到這裏。若是你們想了解更多的內容的話,能夠去掃一掃每篇文章最下面的二維碼,而後關注我們的微信公衆號,瞭解更多的資訊和有價值的內容。
每次整理文章,通常都到2點才睡覺,一週4次左右,挺苦的,還望支持,給點鼓勵