寫在開頭
年前經歷了許多大廠的面試,根據類別整理回顧一些知識點。
一、react+redux部分
1、react Fiber的作用
2、react是同步還是非同步?
react是非同步的,有兩種方式可以處理非同步:
this.setState({
count:this.state.count+1
},function(){
this.setState({count:this.state.count+1});
})
複製程式碼
===========
this.setState((prevState)=>({count:prevState.count+1}));
複製程式碼
3、簡寫redux原理
createStore是redux的核心、暴露出dispatch、subscribe、getState方法給使用者。
function createStore(reducer) {
let state;
let listeners=[];
function getState() {
return state;
}
function dispatch(action) {
state=reducer(state,action);
listeners.forEach(l=>l());
}
function subscribe(listener) {
listeners.push(listener);
return function () {
const index=listeners.indexOf(listener);
listeners.splice(inddx,1);
}
}
dispatch({});
return {
getState,
dispatch,
subscribe
}
}
複製程式碼
4、redux如何更新元件
store.subscribe(()=>this.setState({count:store.getState()}))
複製程式碼
subscribe中新增回撥監聽函式,當dispatch觸發的時候,會執行subscribe listeners中的函式。
subscribe負責監聽改變
5、react如何區別component和dom
當用ReactDOM.render
創造一個dom tree的時候,一般有三種方式:
(1) 第一個引數傳JSX語法糖
ReactDOM.render(
<button color='blue'>OK</button>,
document.getElementById('root')
);
複製程式碼
React.createElement會一個虛擬dom元素。
ReactDOM.render(
React.createElement({
type:'botton',
porps:{
color:'blue',
children:'OK!'
}
}),
document.getElementById('root')
);
複製程式碼
虛擬dom是一個obj:具有一個type屬性代表當前的節點型別,還有節點的屬性props
(2) 函式宣告
function RenderButton() {
return <button color='blue'>OK</button>
}
ReactDOM.render(
<RenderButton />,
document.getElementById('root')
);
複製程式碼
(3) 類宣告
class DangerButton extends Component {
render() {
return <button color='blue'>NOT OK</button>
}
}
ReactDOM.render(
<DangerButton />,
document.getElementById('root')
);
複製程式碼
如果我們組合三種方法建立一個節點:
const DeleteAccount =()=>{
<div>
<p>Are you sure?</p>
<DangerButton>Yep</DangerButton>
<botton color='blue'>Cancel</botton>
</div>
}
複製程式碼
React.createElement會把這個JSX轉換為如下的虛擬DOM:
const DeleteAccount = ()=>{
type:'div',
porps:{
children:[{
type:'p',
props:{
children:'Are you sure?'
}
},{
type:'DangerButton',
props:{
children:'Yep'
}
},{
type: 'botton',
props: {
color: 'blue',
children: 'Cancel'
}
}]
}
}
複製程式碼
當React碰到type是function|class時,它就知道這是個元件了。
6、react 生命週期中有一個被移除
v16.3新引入兩個生命週期:getDerivedStateFromProps,getSnapshotBeforeUpdate
v17.0中將要被移除的三個生命週期:componentWillMount、componentWillReceiveProps、componentWillUpdate
7、react事件機制
其實React事件並沒有原生的繫結在真實的DOM上,而是使用了行為委託方式實現事件機制。
React會將所有的事件都繫結在最外層(document),使用統一的事件監聽,並在冒泡階段處理事件,當掛載或者解除安裝元件時,只需要在通過的在統一的事件監聽位置增加或者刪除物件,因此可以提高效率。
而是在基於Virtual DOM的基礎上實現了合成事件(SyntheticEvent)
因此在事件層次上具有瀏覽器相容性,與原生的瀏覽器事件一樣擁有同樣的介面。
- 使用事件委託技術進行事件代理,React 元件上宣告的事件最終都轉化為 DOM 原生事件,繫結到了 document 這個 DOM 節點上。從而減少了記憶體開銷。
- 自身實現了一套事件冒泡機制,以佇列形式,從觸發事件的元件向父元件回溯,呼叫在 JSX 中繫結的 callback。因此我們也沒法用 event.stopPropagation() 來停止事件傳播,應該使用 React 定義的 event.preventDefault()。
- 所有事件繫結在document上
- 所以事件觸發的都是ReactEventListener的dispatch方法
8、react 兄弟元件的通訊
React 元件間通訊 1.通過中介父元件 child1中呼叫父元件改編child2 state的方法 2.釋出者-訂閱者模式(eventProxy)
child1
eventProxy.trigger('msg', 'end');
child2
eventProxy.on('msg', (msg) => {
this.setState({
msg
});
});
複製程式碼
9、logger中介軟體是在哪一步呼叫的
applymiddleWare()
中介軟體使用這個函式,對store.dispatch方法進行了改造,在發出Action和執行Reducer這兩步之間,新增了其他功能。
二、babel部分
1、babel、babel-polyfill的區別
babel-polyfill:模擬一個es6環境,提供內建物件如Promise和WeakMap 引入babel-polyfill全量包後檔案會變得非常大。它提供了諸如 Promise,Set 以及 Map 之類的內建外掛,這些將汙染全域性作用域,可以編譯原型鏈上的方法。
babel-plugin-transform-runtime & babel-runtime:轉譯器將這些內建外掛起了別名 core-js,這樣你就可以無縫的使用它們,並且無需使用 polyfill。但是無法編譯原型鏈上的方法
babel/preset-react
npm install --save-dev @babel/preset-react
複製程式碼
runtime 編譯器外掛做了以下三件事:
- 當你使用 generators/async 函式時,自動引入 babel-runtime/regenerator 。
- 自動引入 babel-runtime/core-js 並對映 ES6 靜態方法和內建外掛。
- 移除內聯的 Babel helper 並使用模組 babel-runtime/helpers 代替。
三、node部分
1、提高node效能
子執行緒:cluster? 子程式:Node.js Child child_process(spawn()、exec()、execFile()、fork()) 沒答上來(尷尬)
2、node一些api例如fs同步非同步處理問題等
四、webpack部分
1、webpack-sever熱更新機制
當完成編譯的時候,就通過 websocket 傳送給客戶端一個訊息(一個 hash
和 一個ok
)
向client傳送一條更新訊息 當有檔案發生變動的時候,webpack編譯檔案,並通過 websocket 向client傳送一條更新訊息 webpack-dev-server/lib/Server.js:119
compiler.plugin('done', (stats) => {
// 當完成編譯的時候,就通過 websocket 傳送給客戶端一個訊息(一個 `hash` 和 一個`ok`)
this._sendStats(this.sockets, stats.toJson(clientStats));
});
複製程式碼
2、webpack優化問題:多頁面提取公共資源
common-chunk-and-vendor-chunk
optimization: {
splitChunks: {
cacheGroups: {
commons: {
chunks: "initial",
minChunks: 2,//最小重複的次數
minSize: 0//最小提取位元組數
},
vendor: {
test: /node_modules/,
chunks: "initial",
name: "vendor",
}
}
}
}
複製程式碼
3、webpack如何只打包更新修改過的檔案
沒答上來?猜測是entery入口修改??
四、基礎知識部分
1、繼承的幾種方式(es5、es6 class等)
2、css
3、重繪 迴流
4、bind、call、apply的區別,並手寫
//bind返回一個新函式
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
let args = Array.prototype.slice.call(arguments,1)
let _this = this
return function F() {
if (this instanceof F) {
return new _this(...args, ...arguments)
}
_this.apply(context,args.concat([...arguments]))
}
}
Function.prototype.apply = function (context) {
var context = context || window
context.fn = this
var result
if(arguments[1]){
result = context.fn(...arguments[1])
}else{
result = context.fn()
}
delete context.fn
return result
}
複製程式碼
5、Javavscript原型鏈
6、巨集任務微任務
7、柯里化
8、節流防抖
......等等等等
寫在最後
此文是菜鳥本菜對面試中遇到的問題進行總結與思考,有不對的地方大家請幫忙指出~~