開賽前整理了一些常見的 Jr 全端/前/後端工程師面試問題
接下來三十天,廢文連發不中斷,期許自己每天至少學習並分享N個題目,一個月後湊滿一百個題目
平常看熟點,面試時才不怕被問倒><
預計會有以下幾個分類
1.JavaScript 問題
2.Node.js 基礎
3.前端框架和工具
4.網路基礎知識
5.資料庫和數據存儲
6.基本算法和數據結構問題
7.測試相關問題
8.安全性相關問題
9.開發工具和最佳實踐
JS的資料分成兩大類:原始型別(Primitive types)和物件型別(Object types)
**原始型別**:Bool/Null/Undefined/Number/BigInt/String/Symbol(ES6)
**物件型別**:Object
原始型別和物件型別的差異,主要體現在儲存方式、傳遞方式
**存儲方式差異**
### 原始類型(Primitive types):
原始類型的數據直接存儲在它們被聲明的變量中。
當對一個原始類型的變量進行操作時,操作的是變量實際持有的數據值。
### 物件類型(Object types):
物件類型的數據存儲是間接的。物件變量存儲的是記憶體位置的參考(或稱指針)。
當對一個對象變量進行操作時,實際上是在操作對象的引用,而不是實際的對象本身。
舉例來說
```
let num = 10;
let anotherNum = num; // 創建 num 的一個副本
anotherNum = 20; // 修改 anotherNum 的值
console.log(num); // 輸出 10,num 的值沒有改變
let obj = { key: 'value' };
let anotherObj = obj; // anotherObj 現在引用 obj 指向的同一個對象,他們引用同一個記憶體位置
anotherObj.key = 'newValue'; // 這裡這時候修改的是共用記憶體的內容
console.log(obj.key); // 於是輸出 'newValue',obj 的 key 屬性也被改變了
```
**傳遞方式差異(函式調用時)**
#### 原始類型(Primitive types):
原始類型在傳遞給函式時,會複製一份相同的值到函式內使用,而函式內部的操作不會影響原始的值
#### 物件類型(Object types):
物件型別在傳遞給函式時,會**傳遞記憶體地址**到函式內使用,所以韓式內部的操作會影響外部原始的對象
舉例來說
```
let num = 10;
let anotherNum = num; // 創建 num 的一個副本
anotherNum = 20; // 修改 anotherNum 的值
console.log(num); // 輸出 10,num 的值沒有改變
let obj = { key: 'value' };
let anotherObj = obj; // anotherObj 現在引用 obj 指向的同一個對象
anotherObj.key = 'newValue';
console.log(obj.key); // 輸出 'newValue',obj 的 key 屬性也被改變了
```
一般來說使用 const/let 聲明變數時,需要先定義變數,才能使用該變數,不然會報錯
但使用 var 聲明變數時,被聲明的變數具有較廣的作用域(函數作用域或全域作用域),並且在整個作用域都能訪問使用,甚至是在變數被聲明之前,這種行為稱為變量提升.
舉例來說
console.log(x); // 輸出: undefined,而不是錯誤,因為變數 x 被 var 聲明了,不過因為只是"聲明",而不是初始化賦值,所以不會 log "5"
var x = 5;
JavaScript 的主要作用域分以下三種:
全域作用域:所有程式碼的默認作用域
模組作用域:模組模式中運行程式碼的作用域,平常 import/ export 使用模組的時候,每個模組都有自己的模組作用域
函數作用域:由函數建立的作用域,函式裡面宣告的變數,就只能在函式裡面使用,函式外無法調用這些變數
而在 ES6 引入了塊級作用域,使用 let 和 const 聲明的變量只在它們所在的區域中有效,可以避免變數作用域混淆。
參考資料:
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Data_structures
https://developer.mozilla.org/zh-TW/docs/Glossary/Hoisting
https://developer.mozilla.org/zh-CN/docs/Glossary/Scope