一次前端面試的提問總結

記一次比較遙遠的面試提問,記得多少寫多少,附較詳細的解答,歡迎指出錯誤。面試

1. 說說CSS中的相對定位與絕對定位:

  • position: relative;爲相對定位,根據自身位置來進行定位。
  • position: absolute;爲絕對定位,若父級節點的position屬性不爲static,則根據父級節點位置進行定位;不然則繼續尋找上一級position屬性不爲static的節點進行定位,若都沒有找到,則以視窗進行定位。

2. this的指向

  1. 通常狀況下,this指向調用該函數的對象
  2. 箭頭函數裏的this指向定義時所在的對象
  3. this的指向能夠經過bind函數改變

3. 類裏靜態方法的this指向

this指向調用該函數的對象,而靜態方法不用建立實例來調用,而是經過類自己來直接調用,故this指向這個類自己而不是實例。數組

4. letconst

  • let:
  1. 定義的變量只在當前代碼塊有效,存在局部做用域。
  2. 不存在變量提高,即未定義前訪問變量會報錯,而不是返回undefined
  3. 在同一個代碼塊內不容許重複定義同一個變量。
  • const
  1. 擁有let的全部特性
  2. const定義的常量指向的地址不能改變。
  3. 若是定義的是個對象或者數組這種引用類型,只是不能改變它指向的內存地址,但它的屬性能夠改變。

5. 在React組件的render函數裏調用setState會發生什麼問題?哪一個生命週期函數能夠阻止這個問題發生?PureCompoent。

會發生死循環問題,由於setState又會觸發render函數。shouldComponentUpdate生命週期函數返回false的時候不會觸發render,能夠阻止這個問題發生。瀏覽器

PureCompoent在shouldComponentUpdate實現一個淺比較,須要注意的是如下代碼不會觸發render緩存

const newState = this.state.someState;

newState.attr = 'newValue';
this.setState({
    someState: newState,
});
複製代碼

這是由於淺比較是比較這個變量的地址,地址不變則返回false。 下面代碼會觸發render服務器

const newState = this.state.someState;

newState.attr = 'newValue';
this.setState({
    someState: {...newState},
});
複製代碼

還可使用immutable來寫,這裏使用的是immutable的一個輔助庫immutability-helper-x:函數

import update from 'immutability-helper-x';
...

this.setState({
    someState: update.$set(this.state.someState, 'attr', 'newValue'),
});

複製代碼

6. 淺拷貝和深拷貝。

淺拷貝

淺拷貝就是把對象的屬性的值都複製一份到新的內存地址,但只複製一層,若屬性的值爲對象,則仍是原來的引用。如:ui

const obj = {
    child: {
        key: 'value',
    },
};
const newObj = shallowCopy(obj);

console.log(newObj.child === obj.child);  // true
複製代碼

實現方法:this

function shallowCopy(obj) {
    // ES6
    // return {...obj};
    
    return Object.assign({}, obj);
}
複製代碼

深拷貝

而深拷貝則遍歷整個對象,把這個對象全部的值都移到新的內存空間,不存在原來的引用,如:spa

const obj = {
    child: {
        key: 'value',
    },
};
const newObj = deepCopy(obj);

console.log(newObj.child === obj.child);  // false
複製代碼

深拷貝能夠經過遍歷整個對象來拷貝,也有一種比較簡單的實現方法,但效率都比較差。線程

function deepCopy(obj) { 
  return JSON.parse(JSON.stringify(obj)); 
}
複製代碼

7. Node中的事件循環

由於JS是單線程的,執行I/O操做時會阻塞線程,若是一直等待I/O操做完成再執行下面的代碼是不現實的,所以就須要事件循環。

事件循環就是當遇到像I/O這種阻塞線程的操做時,把他們交給系統內核去進行處理,Node繼續往下執行代碼,等到I/O操做執行完後告知Node,而後Node會把響應的回調函數加進事件隊列等待執行。

8. 瀏覽器緩存

強緩存

HTTP狀態碼爲200(from cache),它的優勢是沒有訪問服務器,直接在本地讀取緩存,減小HTTP請求,但也由於如此,這也是它的缺點,由於它不知道服務器資源是否有更新,從而沒法獲取到最新的資源,這個問題一般用給靜態資源添加Hash值來判斷資源有無更新,若Hash值不一樣,則會請求獲取最新資源。

相關Header有(按優先級排序):

  1. Cache-Control。設定一個最大有效期,如Cache-Control: max-age=36000000
  2. Expires。它描述一個最後的過時時間,如Expires: Tue, 17 Jul 2018 15:42:01 GMT

協商緩存

HTTP狀態碼爲304,當沒有強緩存或者強緩存過時時,會發送請求到服務器,若服務器發現資源沒有更新,則返回304告訴客戶端沒必要更新。由於它仍是要發送請求,因此比強緩存慢。

相關Header有:

  1. Last-ModifiedIf-Modified-Since
  2. ETagIf-None-Match

9. 內存泄漏

JS提供自動管理內存,稱爲「垃圾回收機制」,一般用的是「引用計數」,即當一個對象的引用數爲0時就把它釋放回收。而當一個不在使用的對象的引用數又不爲0的時候,沒法把他進行回收,即形成內存泄漏問題。

相關文章
相關標籤/搜索