1. JS的原型与原型链
每一个对象实例都有自己对应的构造器, 对应的构造器都拥有一个prototype的属性, 值为一个plain object,这就是 构造器的原型,而且对象实例的proto属性也指向构造器的原型:
a.__proto__ === A.prototype
所以构造器原型上的属性方法是可以被对象实例访问到。
因为每一个构造器是prototype原型都是一个对象,理论上来说,这个原型对象也可能是另一个构造器的实例,这样就形成了一条原型的链,在原型链上的实例对象,是可以访问到上级原型对象上的属性方法, 原型链的顶层是Object
2. 跨域和同源策略
所谓的同源策略其实是浏览器的一种机制,只允许在同源,也就是同协议、同域名、同端口的的情况下才能进行数据交互。
但是我们在开发项目的过程中, 往往一个项目的接口不止一个域,所以往往就需要做跨域的处理,通常的跨域方式有这么几种:
1、JSONP,主要依赖的是script标签不受同源策略影响,src指向某一个接口的地址, 同步需要传递callback回调函数名字, 这样当接口调用成功后, 本地创建的全局回调函数就会执行, 并且接收到数据。不使用img标签的原因是因为img标签无法执行js语句
2、CORS,依赖服务端对前端的请求头信息进行放行,不做限制。
3、代理访问,前端访问不存在跨域问题的代理服务器,代理服务器再去访问目标服务器(服务器之间没有跨域限制)
3. Redux解决了什么问题?是如何工作的
React框架这样的纯视图的框架对组件通信、状态共享等方面没有太好的解决方案,只能利用状态提升、context之类的技术方案来解决, 但是当组件结构、数据流向都比较复杂的时候,React本身的Api解决这样的问题就有些吃力。
此时就可以使用Flux、Redux这样的架构方式来解决问题。
我们之前的项目就在使用Redux,后来又有了rtk,让redux在react组件中的使用更加方便,在一些小型的项目, 或者一些小模块中, 利用useReducerHook来进行state与dispatch的构建,也能快速优雅的解决问题。
之前的原生Redux中,真实项目开发中,往往需要搭配redux-thunk来进行异步action处理,以及react-redux来进行组件与store的连接, 如果不使用react-redux的话,会比较繁琐。
redux的结构分为store、Views、Actions、Reducer。
Store中存储的状态在视图中可以通过getState来获取,也可以通过subscribe方法进行监听,当视图产生UI操作的时候, 可以调用actions的方法来生成action后,利用dispatch方法进行派发,此时reducer就会被调用,并且接收到当前的状态与action对象, 经过计算出,返回新状态,Store就会进行状态的更新。
利用react-redux后,组件可以通过connect搭配mapStateToProps及mapDispatchToProps参数来获取store中的状态及actions中的方法。
使用RTK之后,创建reducer更近方便,利用useSelector和useDispatch可以更快更高效取用状态及派发action。
对于一个小的场景,比如之前我做的注册模块有三个步骤,每个步骤都需要用到第一步用户填写的手机号等信息,这样就形成了几个小组件间的状态共享, 如果使用父组件状态提升会导致数据流向不清晰,也犯不上使用redux-store进行存储,于是就是使用useReducer快速的创建了一个小的store,内部集成了state与dispatch,搭配Context,也能很高效的解决问题。
4.redux-thunk中间件
这个是解决redux架构中actions方法无法异步返回action的问题的,比如我们在做登录、获取用户信息、获取全局定位城市、获取全局配置等等场景,都是要调用接口异步获取的,此时就可以利用redux-thunk来解决。
thunk中间件的原理其实就是对dispatch进行改写,使其不仅可以接受action对象, 也可以接收一个函数,并且会将dispatch动作及getState方法传入到此函数中,我们就可以在这个函数中进行异步动作,异步执行完成后,再去dispatch对应的action。
5. 说说你了解的Immutable
Immutable是解决Mutable数据操作中的一些问题的,因为JS数据分为引用类型与基础类型, 引用类型在赋值传递的时候往往其实是地址传递,可能会出现一些预料外问题。
Immutable的思想就是构建持久化、不可变的、结构共享的状态,当对immutable数据进行操作的时候,实质上不会更改原数据,而是会根据原数据生成一个新的immutable数据,这样就可以避免刚才说的问题, 并且immutable采用的是结构共享的方式,生成新的immutable数据的时候不会完全重建,而是只重新更改后的节点及其父节点,其他节点与上次的immutable数据共享, 节省了新建的性能开支。
优点:出问题的概率小,更稳定,比起深拷贝来说性能也更高
缺点:需要重新学习Api,学习成本高,也需要额外导入对应的文件, 增加打包体积
其实immutable数据在redux中非常适合,不必再考虑reducer中每次都需要新建新状态的问题,而RTK中已经内部使用了immutable来构建状态。
6. redux是如何通知react数据变更,说通知的过程
redux中store中的状态需要利用getState方法来获取,在组件中更新的场景只有属性和状态变化才能引起组件的re-render,所以在正常开发中,往往需要将store中的状态对应的挂载到组件自身的state上,等到store中状态变化的时候同时更新组件自己的状态,这样就能引起组件的重新渲染最新的数据。
这个时候就需要利用store,.subscribe方法来监听store中状态的变化, 当store中状态变化,组件再去更新自己的状态。
利用react-redux的connect之后,就不要写这样的代码了,因为connect根据mapStateToProps生成的容器组件已经去监听状态变化,UI组件只需要在属性上等待接收即可。
7. React中key的作用
React组件在更新的时候,react就会生成新的完整的虚拟DOM树与之前的虚拟dom进行比对,然后再对有更新的节点相关的位置进行更新。
对比之前往往需要进行匹配和比对,为了匹配的更精准,react希望在列表循环等位置去手动为Element添加key属性,这样对比的时候就可以通过查找key来进行精准匹配。
我之前做项目的时候也碰到过这样的情况,一般都是用数据的id来作为key