年前經歷了許多大廠的面試,根據類別整理回顧一些知識點。css
react是異步的,有兩種方式能夠處理異步:node
this.setState({
count:this.state.count+1
},function(){
this.setState({count:this.state.count+1});
})
複製代碼
===========react
this.setState((prevState)=>({count:prevState.count+1}));
複製代碼
createStore是redux的核心、暴露出dispatch、subscribe、getState方法給使用者。webpack
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
}
}
複製代碼
store.subscribe(()=>this.setState({count:store.getState()}))
複製代碼
subscribe中添加回調監聽函數,當dispatch觸發的時候,會執行subscribe listeners中的函數。es6
subscribe負責監聽改變web
當用ReactDOM.render
創造一個dom tree的時候,通常有三種方式:面試
(1) 第一個參數傳JSX語法糖npm
ReactDOM.render(
<button color='blue'>OK</button>,
document.getElementById('root')
);
複製代碼
React.createElement會一個虛擬dom元素。redux
ReactDOM.render(
React.createElement({
type:'botton',
porps:{
color:'blue',
children:'OK!'
}
}),
document.getElementById('root')
);
複製代碼
虛擬dom是一個obj:具備一個type屬性表明當前的節點類型,還有節點的屬性propsapi
(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時,它就知道這是個組件了。
v16.3新引入兩個生命週期:getDerivedStateFromProps,getSnapshotBeforeUpdate
v17.0中將要被移除的三個生命週期:componentWillMount、componentWillReceiveProps、componentWillUpdate
其實React事件並無原生的綁定在真實的DOM上,而是使用了行爲委託方式實現事件機制。
React會將全部的事件都綁定在最外層(document),使用統一的事件監聽,並在冒泡階段處理事件,當掛載或者卸載組件時,只須要在經過的在統一的事件監聽位置增長或者刪除對象,所以能夠提升效率。
而是在基於Virtual DOM的基礎上實現了合成事件(SyntheticEvent)
所以在事件層次上具備瀏覽器兼容性,與原生的瀏覽器事件同樣擁有一樣的接口。
React 組件間通信 1.經過中介父組件 child1中調用父組件改編child2 state的方法 2.發佈者-訂閱者模式(eventProxy)
child1
eventProxy.trigger('msg', 'end');
child2
eventProxy.on('msg', (msg) => {
this.setState({
msg
});
});
複製代碼
applymiddleWare()
中間件使用這個函數,對store.dispatch方法進行了改造,在發出Action和執行Reducer這兩步之間,添加了其餘功能。
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 編譯器插件作了如下三件事:
子線程:cluster? 子進程:Node.js Child child_process(spawn()、exec()、execFile()、fork()) 沒答上來(尷尬)
當完成編譯的時候,就經過 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));
});
複製代碼
common-chunk-and-vendor-chunk
optimization: {
splitChunks: {
cacheGroups: {
commons: {
chunks: "initial",
minChunks: 2,//最小重複的次數
minSize: 0//最小提取字節數
},
vendor: {
test: /node_modules/,
chunks: "initial",
name: "vendor",
}
}
}
}
複製代碼
沒答上來?猜想是entery入口修改??
一、繼承的幾種方式(es五、es6 class等)
二、css
三、重繪 迴流
四、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
}
複製代碼
五、Javavscript原型鏈
六、宏任務微任務
七、柯里化
八、節流防抖
......等等等等
此文是菜鳥本菜對面試中遇到的問題進行總結與思考,有不對的地方你們請幫忙指出~~