前端面试

≯℡__Kan透↙ 提交于 2020-08-16 03:56:01

1、页面编码和被请求的资源编码如果不一致如何处理?


对于 ajax 请求传递的参数,如果是 get 请求方式,参数如果传递中文,在有些浏览器
会乱码,不同的浏览器对参数编码的处理方式不同,所以对于 get 请求的参数需要使用
encodeURIComponent 函数对参数进行编码处理,后台开发语言都有相应的解码 api。对于 post 请求
不需要进行编码
2、如何避免回调地狱




(1)拆解function:过多的嵌套(缩进)会极大的影响代码的可读性。基于这一点,
可以进行一个最简单的优化----将各个步骤拆解为单个function,
该方法非常简单,具有一定的效果,但是缺少通用性。
(2)事件发布/监听模式:我们可以监听某一件事情,当事情发生的时候,进行相应的回调操作;
另一方面,当某些操作完成后,通过发布事件触发回调。这样就可以将原本捆绑在一起的代码解耦。
events 模块是node原生模块,用node实现这种模式只需要一个事件发布/监听的库。
(3)Promise:Promise是es6的规范
首先,我们需要将异步方法改写成Promise,对于符合node规范的回调函数(第一个参数必须是Error),
可以使用bluebird的promisify方法。该方法接受一个标准的异步方法并返回一个Promise对象
(4)generator:在function关键字后添加*即可将函数变为generator。
执行generator将会返回一个遍历器对象,用于遍历generator内部的状态。
generator函数有一个最大的特点,可以在内部执行的过程中交出程序的控制权,
yield相当于起到了一个暂停的作用;而当一定的情况下,外部又将控制权再移交回来。
我们用generator来封装代码,在异步任务处使用yield关键词,
此时generator会将程序执行权交给其他代码,而在异步任务完成后,调用next方法来恢复yield下方代码的执行。
(5)async/await:














function拆分的方式其实仅仅只是拆分代码块,时常会不利于后续的维护;
事件发布/监听方式模糊了异步方法之间的流程关系;
Promise虽然使得多个嵌套的异步调用能通过链式API进行操作,
但是过多的then也增加了代码的冗余,也对阅读代码中各个阶段的异步任务产生了一定的干扰;
通过generator虽然能提供较好的语法结构,但是毕竟generator与yield的语境用在这里多少还有点不太贴切。



3、从浏览器地址栏输入url到显示页面的步骤


(1)从浏览器接收url到开启网络请求线程(这一部分可以展开浏览器的机制以及进程与线程之间的关系)
(2)开启网络线程到发出一个完整的HTTP请求(这一部分涉及到dns查询,TCP/IP请求,五层因特网协议栈等知识)
(3)从服务器接收到请求到对应后台接收到请求(这一部分可能涉及到负载均衡,安全拦截以及后台内部的处理等等)
(4)后台和前台的HTTP交互(这一部分包括HTTP头部、响应码、报文结构、cookie等知识,可以提下静态资源的cookie优化,以及编码解码,如gzip压缩等)
(5)单独拎出来的缓存问题,HTTP的缓存(这部分包括http缓存头部,ETag,catch-control等)
(6)浏览器接收到HTTP数据包后的解析流程(解析html-词法分析然后解析成dom树、解析css生成css规则树、合并成render树,
然后layout、painting渲染、复合图层的合成、GPU绘制、外链资源的处理、loaded和DOMContentLoaded等)
(7)CSS的可视化格式模型(元素的渲染规则,如包含块,控制框,BFC,IFC等概念)
(8)JS引擎解析过程(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)
(9)其它(可以拓展不同的知识模块,如跨域,web安全,hybrid模式等等内容)








4、什么是 vue 的计算属性?


在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处
理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:
①使得数据处理结构清晰;
②依赖于数据,数据更新,处理结果自动更新;
③计算属性内部 this 指向 vm 实例;
④在 template 调用时,直接写计算属性名即可;
⑤常用的是 getter 方法,获取数据,也可以使用 set 方法改变数据;
⑥相较于 methods,不管依赖的数据变不变,methods 都会重新计算,但是依赖数
据不变的时候 computed 从缓存中获取,不会重新计算







5、调用 setState 之后发生了什么?


在代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合
并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。在
React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据
差异对界面进行最小化重渲染。在差异计算算法中,React 能够相对精确地知道哪
些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲
染。




6、react中的JSX原理


用 JavaScript 对象来表现一个 DOM 元素的结构JavaScript 写起来太长了,结构看起来又不清晰,用 HTML 的方式写起来就方便很多了。

于是 React.js 就把 JavaScript 的语法扩展了一下,让 JavaScript 语言能够支持这种直接
在 JavaScript 代码里面编写类似 HTML 标签结构的语法,
这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换成 JavaScript 的对象结构。
React.createElement 会构建一个 JavaScript 对象来描述你 HTML 结构的信息,包括标签名、属性、还有子元素等,
jsx实际上就是一种javascript对象,他经过react语法的构造,还有编译转化,最后得到dom元素,可以插到页面中:
所谓的 JSX 其实就是 JavaScript 对象,所以使用 React 和 JSX 的时候一定要经过编译的过程:
JSX —使用react构造组件,bable进行编译—> JavaScript对象 — ReactDOM.render()—>DOM元素 —>插入页面





易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!