這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
為了保證的可讀性,本文采用意譯而非直譯,
在 JS 面試中,經常會看到一些簡單而又沙雕的題目,這些題目包含一些陷阱,但這些在我們規范的編碼下或者業務中基本不會出現, 有些面試官就是這樣,不專注于制定代碼的標準和規范上,卻用不規范的代碼去檢驗別人是否細心,
這魔幻的世界就是一個攀比優越感的,我能考你,我就是比你優越,真實,
來看看這 7 個沙雕題目是哪些,
1. 偶然創建的全域變數
面試官問
在下面的代碼中 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 的全域變數
2. 陣列的 length 屬性
面試官問
clothes[0] 的值是什么?(沙雕)
const clothes = ['jacket', 't-shirt']; clothes.length = 0; clothes[0]; // => ???
答案
陣列物件的 length 屬性具有一些特殊的行為:
減少
length屬性的值的副作用是洗掉自己的陣列元素,這些元素的陣列索引位于新舊長度值之間,
由于 length 屬性行為,當 JS 執行 clothes.length = 0 時,洗掉所有的 clothes 項, 所以 clothes[0] 的值為 undefined,因為 clothes 陣列已被清空,
3.考驗眼力的魔幻題
面試官問
下面代碼中 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]
用不規范的代碼去檢驗別人是否細心,我覺得很沙雕,
4.自動分號插入
面試官問
arrayFromValue() 回傳什么值?(沙雕)
function arrayFromValue(items) {
return
[items];
}
arrayFromValue(10); // => ???
答案
這里需要注意的 return 和 [items] 之間已經換行了,JS 會在換行之間自動插入分號,所以上面等價下面的代碼:
function arrayFromValue(items) {
return;
[items];
}
arrayFromValue(10); // => undefined
return;在函式內部使該函式回傳 undefined,所以 arrayFromValue(10) 的值為 undefined,
5. 被考爛的一個經典閉包問題
面試官問
下面的代碼執行結果是什么?(能不能換個題)
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 的原因
6. 浮點運算
面試官問
下面的代碼輸出是什么? (能不能換個題)
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,
7. 變數的提升
面試官問
如果在宣告之前訪問 myVar 和 myConst 會發生什么?(能不能換個題)
myVar; // => ??? myConst; // => ??? var myVar = 'value'; const myConst = 3.14;
答案
提升和時間死區是影響 JS 變數生命周期的兩個重要概念,

在宣告之前訪問 myVar 的結果是 undefined,因為使用 var 宣告的變數會被提升且值為 undefined,
但是,在宣告行之前訪問 myConst 會引發 ReferenceError,在代碼行 const myConst = 3.14 之前,const 變數處于臨時死區,
本文轉載于:
https://juejin.cn/post/6844903974374473736
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/554710.html
標籤:JavaScript
上一篇:原生AJAX的學習
下一篇:返回列表

