年前经历了许多大厂的面试,根据类别整理回顾一些知识点。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原型链
六、宏任务微任务
七、柯里化
八、节流防抖
......等等等等
此文是菜鸟本菜对面试中遇到的问题进行总结与思考,有不对的地方你们请帮忙指出~~