React 新老版生命周期函数
老版生命周期函数:
新版生命周期函数:
Render函数靠mouting时触发,如果在里面调用状态会造成死循环
componentWillMount
相当于vue中的beforemount,在dom渲染之前触发的
componentDidMount
在dom渲染完之后,是一个创建时期调用的钩子
componentWillReceiveProps(props.state)
检测父组件给的信息,一有变化就会run
componentWillUnmount
在组件被卸载时调用
shouldComponentUpdata钩子:
此钩子新老版生命周期函数中都存在,主要用于在渲染之前,判断是否执行渲染,相当于一个开关,当执行结果为false时不会触发后面的render函数。那么我们就可以利用此钩子去做一些优化的操作,例如我们都知道父组件渲染时会带着子组件一起渲染,但有的时候子组件的数据并没有发生变化但还是会带着被渲染一次,就造成了不必要的性能浪费,这个时候在shouldComponentUpdata中加一层判断的话就可以解决这个问题。(当然,在创建组件时如果将继承的Component改成PureComponent,可帮忙做上面的优化)
getDerivedStateFromProps
这是一个新增的钩子,此钩子的处罚比较频繁,当组件被传入值时,不管相不相等都会执行,数据更新时也会执行(不管自身还是父组件传来的)
this.forceupdate()
强制渲染
getSnapshotBeforeUpdate
在DOM渲染之前获得一个快照
从启动webpack构建到输出结果经历了一系列过程,它们是什么
- 解析webpack配置参数,合并从shell传入和webpack.config.js文件里配置的参数,生产最后的配置结果。
- 注册所有配置的插件,好让插件监听webpack构建生命周期的事件节点,以做出对应的反应。
- 从配置的entry入口文件开始解析文件构建AST语法树,找出每个文件所依赖的文件,递归下去。
- 在解析文件递归的过程中根据文件类型和loader配置找出合适的loader用来对文件进行转换。
- 递归完后得到每个文件的最终结果,根据entry配置生成代码块chunk。
- 输出所有chunk到文件系统。
vue react 怎么检测数据变化的
Vue
vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
React
react状态变化只能通过setState,调用setState就会更新状态重新渲染dom
instanceof 的原理是什么?
实际上这里我们可以自己去手写一个Instanceof去分析
function myInstanceof(left, right) {
let prototype = right.prototype
left = left.__proto__
while (true) {
if (left === null || left === undefined)
return false
if (prototype === left)
return true
left = left.__proto__
}
}
上述代码思路:
首先获取类型的原型
然后获得对象的原型
然后一直循环判断对象的原型是否等于类型的原型,直到对象原型为 null,因为原型链最终为 null
React中怎么让setState同步更新?
回调,promise,async+await
回调
setState函数的第二个参数允许传入回调函数,在状态更新完毕后进行调用,例如下面的这个例子
this.setState({
data: '666'
}, () => {
console.log('加载完成')
});
promise
利用promise的特性,可以使用promise封装一个函数去一劳永逸的解决这个问题
setStateAsync(state) {
return new Promise((resolve) => {
this.setState(state, resolve)
});
}
async+await
相当于promise的优雅版,我们可以利用await"等一等"的特性去让程序等待await后面的函数做完以后再执行下面的代码(当然,await必须要配合async使用),例如下面的小例子
async myfun(){
await this.setState({
data: '666'
});
}
什么是immutable, 为什么要使用它
什么是 Immutable Data
1.Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象
2.Immutable 实现的原理是 Persistent Data Structure (持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变
TIP:当然,通过这一点,我们可以去做时间旅行,也就是以前调用之前存在过的旧数据。
3.同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗, Immutable 使用了 Structural Sharing···· (结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。
TIP:例如有下图的一个数据结构(灵魂画手就是我了):
例如我们现在数据C2发生改变,那么他只会影响到B2与A,其他不会受到影响的数据直接复制过来就好了无需重新进行操作,性能有所提升。
关于具体的优缺点可以看下图
浏览器端 Event loop
执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去检查微任务(
microTask
)队列是否为空,如果为空的话,就执行Task
(宏任务),否则就一次性执行完所有微任务。
每次单个宏任务执行完毕后,检查微任务(microTask
)队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务(microTask
)后,设置微任务(microTask
)队列为null
,然后再执行宏任务,如此循环。
你都做过哪些Vue的性能优化
SPA 页面采用keep-alive缓存组件
在更多的情况下,使用v-if替代v-show
第三方模块按需导入
服务端渲染SSR
压缩代码
Tree Shaking
sourceMap优化
服务端开启gzip压缩
nextTick知道吗,实现原理是什么
nextTick
批量异步更新策略,一句话概括在下次DOM更新循环结束之后执行延迟回调。它主要是为了解决:例如一个data
中的数据它的改变会导致视图的更新,而在某一个很短的时间被改变了很多次,假如是1000次,每一次的改变如果都都将促发数据中的setter
并按流程跑下来直到修改真实DOM,那DOM就会被更新1000次,这样的做法肯定是非常低效的。而在目前浏览器平台并没有实现
nextTick
方法,所以Vue.js 源码中分别用Promise
、setTimeout
、setImmediate
等方式定义了一个异步方法nextTick,它接收的是一个回调函数,多次调用nextTick会将传入的回调函数存入队列中,当当前栈的任务都执行完毕之后才来执行这个队列中刚刚存储的那些回调函数,并且通过这个异步方法清空当前队列。
什么是 JSX
JSX是javascript的语法扩展。它就像一个拥有javascript全部功能的模板语言 在里面可以使用js代码{}
它实现的原理就是react封装了createElement(第一个参数是 标签名,第二个参数是对象 包含了所有的属性,第三个是 子节点)。
跨域的解决方案
跨域问题来源于浏览器同源策略的限制问题导致的
而浏览器设置同源策略是因为 防止浏览器收到xss 和 csrf的工资
第一种:可以通过JSONP的原理:img ,script,link。
jsonp只支持get的请求方式,也容易受到
xss
的攻击第二种:后端设置cros
第三种:服务器代理
第四种:sock
注:上述图片及部分理论知识来源于于官方文档,给出的答案深度只对于面试时使用,如想深入了解还需观看官方文档(例如immutable的各种API等等)