Huang Pei
14 min readApr 27, 2020

JS面試題目整理 JavaScript Interview Prep: Practice Problems 1~10

其實課程才 4 小時滿短的,但裡面的 30 題都是滿重點的觀念題,很適合拿來在面試前作為複習。

Triple Add Function/ Working With IIFEs/ Button 5/Closure/This/ Hoisting/ Scope and “self”/ Equals vs Strict Equals/ Log Number Function

本筆記出自:JavaScript Interview Prep: Practice Problems

  1. Triple Add Function
問題:tripleAdd(10)(20)(30);// returns total of all 3 numbers added together

key:我們能觸發的只有函數。我們並非觸發三次tripleAdd函式,而是觸發了一次後,回傳了一個函式,於是再觸發回傳的函式,而又再回傳了一個函式,於是再觸發回傳的函式。(想想閉包)

解:function tripleAdd(num1) {
return function (num2) {
return function (num3) {
return (num1 + num2 + num3)}
}
}
tripleAdd(10)(20)(30);

延伸觀念:

Currying Function (函式柯里化)

Is the technique of translating one function that takes multiple arguments into a sequence of functions that each take a single argument .

將一個接收複數參數的函式轉為一連串接收單一參數的函式。

function tripleAdd1(num1, num2, num3) {
return num1 + num2 + num3 }
tripleAdd1(10, 20, 30)
_____
柯里化後:function tripleAdd(num1) {
return function (num2) {
return function (num3) {
return (num1 + num2 + num3);}
}
}
tripleAdd(10)(20)(30);
_____
變形版,依然是柯里化函數:function quadrupleAdd(num1) {
return function(num2) {
return function(num3, num4) {
return num1 + num2 + num3 + num4;}
}
}
quadrupleAdd(10)(20)(30, 40);

推薦整理文:Currying in JavaScript(柯里化)

2. Working With IIFEs

問題:1. What is an IIFE and why they used?2. Code out an example IIFE that functions properly.

自己的回答:

  1. 立即執行的函數,可以避免變數污染的問題。
  2. 恩不是很熟ry(寫不出能夠闡述變數不被污染的例子)
var greeting = ‘yo’;(function(name) {
var greeting=’Hi’
return console.log(greeting + name)})(‘Iris’);

看完解答感覺自己寫得還行。

IIFE (Immediately Invoked Function Expression)

1. 使用Grouping Operator () 包起來的 anonymous function。這樣的寫法可以避免裡面的變數污染到 global scope。

2. 馬上執行 function 的 expression (),JavaScript 引擎看到它就會立刻轉譯該 function。

解:1. Immediately Invoked Function Expression: 
A function that is executed right after it is created.
(定義完馬上就執行的函式)
2.(function(num){
return num*2 })(10)
The main reason to use and IIFE is to preserve a private scope within your function inside of your javascript code you want to make sure that you are not overriding any global variables.(使用IIFE的主要目的是為了避免function內的變數覆寫掉全域變數)

相關文章:之前寫得複習

3. Button 5

問題:
1.依序列印五個按鈕,請問按鈕上的數字個別為何?
2.請問點擊後 alert 會顯示什麼?
3.那又該如何正確顯示 alert 的數值?
function createButtons() { for (var i = 1; i <= 5; i++) {
var body = document.getElementsByTagName(‘BODY’)[0];
var button = document.createElement(‘BUTTON’);
button.innerHTML = ‘Button ‘ + i;
button.onclick = function() {
alert(‘This is button ‘ + i)
};
body.appendChild(button);
};
};
createButtons();

複習之前寫的文章:了解閉包(一)了解閉包(二)

解:1. 當 createButtons 執行時,會依序列印出 i = 0, 1, 2, 3, 4, 5 的按鈕。2. 而此時 i 已經跑到了 5 ,而監聽的函數並未執行,當點擊按鈕後才開始呼叫 alert(‘This is button ‘ + i) ,這時再跑時因為 i++,所以 i = 5 會再 +1 ,此時 i = 6,因此每個按鈕都會輸出 This is button 6 的訊息。3. 法一:IIFE在執行迴圈當下執行IIFE並傳入當下的 i,並在IIFE的記憶體空間內保存為 j ,而裡頭的匿名函式在被呼叫時,就可以使用被保存的 j 值。function createButtons() {
for (var i = 1; i <= 5; i++) {
var body = document.getElementsByTagName(‘BODY’)[0];
var button = document.createElement(‘BUTTON’);
button.innerHTML = ‘Button ‘ + i;
(function(j){
button.onclick = function() {
alert(‘This is button ‘ + j)}})(i);
body.appendChild(button);
};
};
createButtons();_____法二:letlet 的作用域是 block {},因此 i 會被鎖在 {} 中 而不會成為全域變數不斷被累加,因此被呼叫時能維持本來的值。function createButtons() {
for (let i = 1; i <= 5; i++) {
var body = document.getElementsByTagName(‘BODY’)[0];
var button = document.createElement(‘BUTTON’);
button.innerHTML = ‘Button ‘ + i;
button.onclick = function() {
alert(‘This is button ‘ + i)};
body.appendChild(button);
};
};
createButtons();參考文章:鐵人賽:ES6 開始的新生活 let, const

4. Closure

問題:1. What is a Closure?2. Code out an example closure that functions properly.

自己的回答:

  1. 當外層的函式執行完離開堆疊後,執行環境會保留其記憶體與變數的狀態,使內層的函數得以繼續取用

2.

function wallet() {
let origin = 100;

return function saveMoney(save) {
origin = origin + save;
return console.log(origin)}
}
let money = wallet();
money(10) //110
money(20) //130

複習之前寫得文章:了解閉包(一)

解:(我覺得這個講得有點複雜)1.  A closure is an inner function that has access to the scope of an enclosing function.  A closure has access to variables in 3 separate scopes:    1. Variables in its own scope.
2. Variables in the scope of the outer function.
3. Variables in the globe scope.
The closure also has access to: 1. Its own parameters.
2. Parameters of outer function(s).
2.const globalVariable = ‘global var’;
function outterFunc(param1) {
const variable1 = ‘var one’;
function innerFunc(param2) {
const variable2 = ‘var two’;
console.log(‘globalVariable: ‘, globalVariable) //可取用全域變數
console.log(‘variable1: ‘, variable1) //可取用外層變數
console.log(‘variable2: ‘, variable2) //可取用本身變數
console.log(‘param1: ‘, param1); //可取用外層參數
console.log(‘param2: ‘, param2)} //可取用本身參數
innerFunc(‘param one’);}outterFunc(‘param two’);

5. This

問題:What is the ‘This’ keyword and how is it used?

覺得題目講解得普通,還是參考之前寫得文章好了:克服JS奇怪的部分_This

- this 是 JavaScript 的一個關鍵字。

- this 是 function 執行時,自動生成的一個內部物件。

- 隨著 function 執行場合的不同,this 所指向的值,也會有所不同。

- 在大多數的情況下, this 代表的就是呼叫 function 的物件 (Owner Object of the function)。

總之直接背起來吧😂

6. Hoisting

問題:Describe what variables and functions hoisting is and how it works

自己的回答:

在變數及函數創造階段時,在記憶體空下位置,函式(陳述式)會預先納入記憶體中,而變數則會預先給予 undefined 的值。

參考之前寫得文章:克服JS奇怪的部分_創造與提升、JS 與

解:(覺得上面的解就夠了)The javascript interpreter looks ahead in the code to find all of the variable and function declarations and then hoists those declarations to the top of the file.

*補充:var 是看 function scope 提升到 global 或 function 的最上端,而 const 與 let 是 block scope ,所以要特別注意!

function getTotal() {  console.log(multiplier);
console.log(total);
let total = 0; for (var i = 0; i < 10; i++) { let valueToAdd = i;
var multiplier = 2;
total += valueToAdd * multiplier }
return total }getTotal()

拆解後

function getTotal() {  console.log(multiplier) //undefined
console.log(total) //Uncaught ReferenceError (let產生暫時性死區)
let total;
var multiplier;
total = 0;
for (var i = 0; i < 10; i++) { valueToAdd = i;
multiplier = 2;
total += valueToAdd * multiplier }
return total }getTotal()

詳細可以參考這篇文:一次說清楚 JavaScript 中宣告的各種提升行為(var、function、let/const)

7. Scope and “self”

問題:求執行結果var myCar = {
color: ‘Blue’,
logColor: function() {
var self = this;
console.log(‘In logColor — this.color: ‘ + this.color);
console.log(‘In logColor — self.color: ‘ + self.color);
(function() {
console.log(‘In IIFE — this.color: ‘ + this.color);
console.log(‘In IIFE — self.color: ‘ + self.color)})()},
}
myCar.logColor();

自己的回答:‘Blue’/ ‘Blue’/ undefined/‘Blue’ (正確)

This 指向呼叫 function 的物件,在 method 中的 IIFE 函式的 this 會指向 global,而 global 中的 color 會是 undefined,因此需要使用 self 將當下的 this 給保存起來。

因此 logColor 此 method 中this 與 self 的值相同都是 ‘Blue’,而 IIFE 中的 this 沒被保存所以變成undefined,而 self 有將 this 保存起來因此可以正確顯示 ‘Blue’。

詳細可以參考這篇文章:鐵人賽:JavaScript 的 this 到底是誰?

*題外話,如果在 global設定 var color = ‘Red’,那 console 的結果就會是 ‘Red’,但如果設定 let color = ‘Red’ 則依然是 undefined,因為 var 會將變數設定成 window 物件下的屬性,所以 window.color = ‘Red’,然而 let 不會,所以在 window 下找不到 color 這個屬性,因此會是 undefined。

詳細可以參考這篇文最下半部:淺談 var 與 let 的差異以及有無宣告變數的差異

8. Equals vs Strict Equals

問題:What is the difference between the comparison operators == and ===?

自己的回答:== 是寬鬆判定不看型別,===嚴格判定會看型別。

*轉型相關補充

10. Log Number Function

問題:求console.log值?var num = 50;function logNumber() {
console.log(num);
var num = 100;
}
logNumber();

自己的回答:

問題:求console.log值?var num = 50;function logNumber() {
var num; //提升
console.log(num) //undefined
num = 100;
}
logNumber();

*補充:若變數改用 let 宣告,則會產生暫時性死區問題。

var num = 50;function logNumber() {
console.log(num); //Err
let num = 100;
}
logNumber();
Huang Pei

記錄用倉庫,歡迎指正。菜鳥前端,最菜的那種(超能力少女です)。