# 前端工程師 javascript 面試問題紀錄 近期開始面試多家公司,這邊整理出筆試或面試上遇到的問題,希望可以幫助到需要的人還有我自己也能複習。 **[參考網址做額外補充!](https://www.explainthis.io/zh-hant/swe-questions/frontend)** ### 下列有哪些屬性是傳址(call by reference)特性? > Array、Number、Function、Object、String、Undefined **ans:** || Array、Function、Object || 說明: js的資料類型(data type)分為兩大類,一種是原始型別(primitive type)和物件(object)。 - 原始型別有: - Number - String - Null - BigInt - Boolean - **Undefined** - Symbol - Object: - 除了原始型態以外的型態,如 array、function、object、map... 簡單說明結論,object型態的類型基本上就是傳址的特性,在呼叫使用時,會是使用到該物件上的地址,如果在物件屬性中重新賦值的話會有參考改變的特性,需要注意。 --- ### 下列輸出結果為? 1. console.log(undefined === undefined); 2. console.log(NaN == NaN); 3. console.log(isNaN('NIHOW')); 4. console.log({} === '[object Object]'); 5. console.log(0.1+0.2 == 0.3); 6. console.log(typeof[1,2,3]== 'array'); 7. console.log(null == undefined); 8. console.log(null === undefined); **ans:** || 1. true 2. false 3. true 4. false 5. false 6. false 7. true 8. false|| --- ### 請解釋變數和函式宣告提升(Hoisting)? 下列結果為? ```javascript! function foo(param) { console.log(num); console.log(param); console.log(arguments[1]); say(); var num = 1; function say(){ console.log(2+num); } return 33; } foo('4','5'); ``` **ans:** 1. 變數提升: 當使用`var`宣告時,此變數會被提升到其所在函式或作用域的頂部,表示可以再宣告前就使用該變數,但是他的值會是`undefined`。 2. 函數提升: js中的function也會如此,因此也能在函數宣告之前就調用了。 3. || undefined '4' '5' NaN || 答案說明:要注意看宣告前後,我在寫題目時寫出的答案是錯的,因為我沒有注意到`say()`函式執行下` var num` 的位置,所以答錯了QQ。 --- ### 請問下列 A、B、C、D、E、F 各自打印了幾次? ```javascript! for(let i = 0; i <= 10; i++) { console.log('A'); for(let j = 0; j < 10; j++) { console.log('B'); if(i == 3 && j == 6) { console.log('C'); } if(i==j) { console.log('D'); } if(i&&j) { consolog.log('E'); } } } ``` **ans:** ||A: 11 次(0~10共11次打印) B: 110 次(第一層陣列11次 x 第二層陣列10次(<=10) = 110) C: 1 次 D: 10 次(i跟j為0~9時才會打印,所以是10次) E: 90 次(這個判斷相等於判斷i跟j是否都不是0也就是說判斷是否存在)|| ```javascript! let j = 0; while(j <= 100) { console.log('F') } ``` **ans:** || 無限次 因為沒有設置終止條件,可以在log下面增加 j++; 就不會無限打印了 || --- ### 1綜合判斷 : ```javascript! var obj ={}; console.log(delete obj.p); ``` **ans:** || true || ### 2綜合判斷 : ```javascript! const a = {} const b = {key: 'b'} const c = {key: 'c'} a[b] = 123 a[c] = 456 console.log(a[b]) ``` **ans:** || 456 || ### 3綜合判斷 : ```javascript! let obj = {name:'jimmy', age:18}; let obj1 = obj; obj.name = 'chimmy' console.log(obj1) obj1 = {} obj.age = 22 console.log(obj1) ``` **ans:** || {name: 'chimmy', age: 18} {} || 說明: ||注意重新賦值的位置,當obj1重新賦值後他就不再和obj1為相同位"址"了,所以會是空的。|| ### 4綜合判斷: ```javascript! var f = function() { console.log('1'); } function f(){ console.log('2'); } f() ``` **ans:** || 1 || 說明: 因為提升的關係,`var f` 跟 `function f` 都被提升到最頂部,接著執行賦值的 `function() {console.log('1')}`,因為函數聲明(就是"=")會覆蓋函式,所以當在使用`f()`其實就只會觸發到聲明中的log '1'。 ### 5綜合判斷: ```javascript! function Student(name) { this.name = name; console.log(this); } var result = new Student('jimmy'); ``` **ans:** || Student {name: 'jimmy'} || ### 6綜合判斷: ```javascript! var name = 'jimmy'; var student = { name: 'chimmy', doSth: function() { console.log(this.name) }, doSth2: function() { var arrowDoSth = () => { console.log(this.name); } arrowDoSth(); }, doSth3: () => { console.log(this.name); } } student.doSth() student.doSth2() student.doSth3() ``` **ans:** || 'chimmy' 'chimmy' 'jimmy'|| 說明: 箭頭函式不會創造自己的`this`,所以看到箭頭函式要往上看他繼承的外部函式的this對象,外部函式只到誰,箭頭函式的this就會是誰,所以doSth2中的this其實也指向student本身。 ### 1請寫出下列程式碼執行結果: ```javascript! var name = 'my name is window' var obj = { name: 'my name is obj', fn: function () { setTimeout( () => { console.log(this.name) }, 1000) } } obj.fn() ``` || my name is obj || 說明: 因為閉包的特性,函式在使用時會保留上下文所以就算外面有個全域變數,箭頭函式下的this還是會指回原本的obj當中。 ### 2請寫出下列程式碼執行結果: ```javascript! const obj = {a:'one', b:'two', a: 'three'} console.log(obj) ``` ||SybtaxError 重複屬性名|| ### 請倒敘印出Array中的內容,並且使用Array.prototype中的reduce完成 ```javascript! const numbers = [0,1,2,3,4,5,6,7] function revertNumbers(params){ const ans = [] params.reduce(function(total, el) { ans.unshift(el) return total // 返回已累積的陣列 },[])// 空陣列是提供reduce方法做初始的累積紀錄 // 如果要回傳字串就用ans.join('') return ans } revertNumbers(numbers) ```