原文链接目录查看

js根底

数据类型5+1

根本类型 ——numberstringundefindbooleannull;
援用类型——Object;
目前根本类型中增加了一个新成员:symbol;
根本类型和援用类型区别:前者按值拜访,因而为咱们操作的就是存储在变量中的理论值;后者不能间接操作对象所在的内存空间,在操作对象时,实际操作的是该对象的援用。
根本类型存储在中;援用类型的 ‘变量’名称 存储在中,同时存储指针,该指针指向中的实在的值;(概念能够间接搜寻 "js中栈和堆的概念和区别")
参考书:犀牛书

this指向

箭头函数:this继承包裹箭头函数的第一个一般函数中的this;
一般函数:new(this指向新对象)——bind/apply/call(this是强制指向的this)——this指向函数上下文对象——this指向window;
参考文章:https://juejin.cn/post/6844903941021384711
参考书:红宝书

闭包

一个函数援用另外一个函数外部变量就会造成闭包,闭包在平时开发中十分的多见;了解作用域链创立和应用的细节对了解闭包十分重要;
参考文章:https://juejin.cn/post/6844903747957719053
参考书:红宝书

原型

每个对象被创立开始,就与另一个对象关联,从另一个对象上继承其属性,这里的另一个对象就是原型;
原型存在的意义就是组成原型链。当范文一个对象属性时,先从对象自身找,找不到就去对象原型上找,如果还找不到,就去对象原型的原型上找,如此类推,直到找到为止;这条由对象及原型组成的查找链条就是原型链;
参考文章:https://juejin.cn/post/6844903936365690894
参考书:红宝书

继承

组合继承:通过 call批改子类this,将子类原型指向 new 父类();
寄生组合继承:通过 call 批改子类this,将子类原型指向父类原型(Object.create(父类.prototype)) ,并将子类原型构造函数指向子类;
参考书:红宝书

模块化

模块化特点:复用性、可维护性;
commonJs最早作为规范在NodeJs中引入, 作为NodeJs模块化规范;在commonJs中,require首次加载就会执行整个脚本,在内存中生成一个对象缓存下来,下次加载时可间接从缓存获取;
对于循环加载,只输入已执行的局部。还未执行局部不输入;
最新ES6的 ES Module,是动态加载;脚本被加载时,成为一个指向被加载模块的援用,不会缓存;

并发和并行

区别:并发是两个或多个事件在同一时间距离内产生;并行是指两个或多个事件在同一时刻内产生;
并行通过晋升硬件能力,只须要多核CPU即可达到;
并发中最常听到的就是高并发,在肯定工夫,服务器的吞吐量和QPS每秒响应申请数都是肯定的。而在这样的状况下,要解决高并发的问题,最简略当然是晋升机器性能,加内存,加硬盘,降级网速。当然,通过架构层面设计,也能够做点货色,部署多台机器,增加负载平衡层,将申请平均;将数据库分库分表并读写拆散;引入消息中间件等;缓存集群引入;

异步计划

回调函数:在浏览器端,异步问题就是Ajax网络申请响应异步,而回调函数能够肯定水平解决这个响应异步的问题,毛病是:不易保护、不易读、不能间接return;

Generator:封装多个外部状态的异步解决方案,生成器函数;会返回一个迭代器,配合next()函数,能够管制开始、暂停和复原代码;
场景:控制流治理、异步操作;

Promise:解决异步操作计划,蕴含异步操作后果的对象;外部存在三种状态,一旦开始不可更改状态;问题:无奈勾销,谬误须要回调捕捉;Promise是链式调用,每次调用then之后返回一个Promise,并且是一个全新的Promise;
Promise实现根据Promise/A+标准——
三种状态:pedding、fulfilled、rejected;
(Promise封装的Ajax为例子)进行异步解决流:执行Promise回调函数,因为异步操作,外部状态未变动。继续执行then回调,外部状态未变动,回调队列中then回调临时不执行。此时,异步执行实现(网络申请响应),状态变动,Promise外部调用resolve函数,回调队列执行;
async/await:异步解决方案,须要配套应用;函数增加async后,函数会返回一个Promise;await外部实现了Generator,await是异步操作,起初的表达式不返回Promise的话,就会包装成Promise.resolve(返回值 ),而后去执行函数外的同步代码;

事件循环

一个事件循环又一个货多个工作队列;一个工作队列是一组工作;
1. 每个事件循环是一个正在运行的工作,它能够是一个工作或null;2. 每个事件循环具备microtask队列(微工作队列),最后为空;3. 每个事件循环都有一个执行微工作检查点的布尔值,该布尔值最后为false;

1. js的事件循环如何环执行?

浏览器事件循环执行程序:

  1. 首先执行script脚本同步代码,属于宏工作;
  2. 当执行完以后所有同步工作后,执行栈为空,查问是否有异步工作代码须要执行;
  3. 执行以后宏工作下的所有微工作;
  4. 微工作执行完之后,如有必要会渲染页面;
  5. 而后开始下一轮事件循环;

2. 宏工作和微工作有哪些?

宏工作:script、setTimeout、setInterval、setImmediate、I/O、UI Render;
微工作:process.nextTick、promise、MutationObsever;


3. Nodejs的事件循环和浏览器事件循环区别?

Nodejs和浏览器端,宏工作和微工作交替执行,调用程序基本相同。Nodejs执行会进行阶段辨别,分为6个阶段:参考:Node.js 事件循环文档,每进入某个阶段,会从回调队列中取出函数执行。当队列为空或回调函数达到零碎设定阈值,就进入下一个阶段。


异步计划

能够把ajax异步回调作为浏览器端的最后的异步解决方案,异步回调 ———> Promise实例 ——> Generator ——> async/await,大抵是一个这样的线,咱们须要关注的可能次要就是Promise 和 async/await的计划。

1. Promise外部实现理解嘛?它的具体工作流程是怎么样的?

Promise是异步解决方案,蕴含异步操作后果的对象,特点:外部存在三种状态,状态一旦变动不可更改状态;Promise是链式调用,每次调用then回调函数都会返回一个新的Promise,并且是一个全新的Promise;
Promise异步解决流:执行Promise实例回调函数,因为异步申请或者操作,此时状态未变动。继续执行then回调,因为状态未变动回调会被放入回调数组中。直到Promise实例中异步申请或者操作实现,状态发生变化,调用resolve函数,回调数组遍历执行,then回调函数拿到相干数据


2. 说一说async/await

参考:
Promise原理解析
图解Promise流程

浏览器渲染原理

浏览器是多过程利用,每关上一个Tab页,就相当于创立了一个独立的浏览器过程。浏览器过程有:Browser过程(主过程)、插件过程、GPU过程、渲染过程(浏览器内核)。主过程只有一个是负责协调利用,同时默认每个Tab页面一个渲染过程,互不影响。咱们常说的Js线程、GUI渲染线程就蕴含在渲染过程之中,还包含异步http申请线程、事件触发线程等。

1. 地址栏输出域名地址之后产生了什么?

1. DNS服务查问域名对应的指标服务IP地址;2. 依据指标IP地址查找到指标服务器,并建设TCP连贯;3. 服务器响应返回数据或文本信息等;4. 客户端获取到数据之后进行页面渲染;

2. 浏览器渲染的流程?

1. 申请html文件解决html标记构建DOM树;2. 申请css文件解决css标记构建CSSOM树;3. 将DOM和CSSOM合并成一个渲染树;4. 依据渲染树布局,以计算每个节点的几何信息;5. 将各节点绘制在屏幕上;

存在阻塞的css资源时,浏览器会提早JS的执行和DOM的构建;

3. 重绘和回流?

重绘是当节点须要更改外观而不影响布局;回流是布局或几何属性须要扭转;
参考:渲染性能
参考:
从浏览器多过程到JS单线程
你不晓得的浏览器页面渲染机制

网络协议


对于TCP和UDP的介绍、TCP的三次握手和四次挥手就不细说,相干文章能够参考:[传输层协定TCP和UDP
](https://juejin.cn/post/684490...),TCP三次握手和四次挥手
http协定是罕用的网络传输协定,全称是超文本传输协定,它规定了http申请和响应的具体构造,当然还蕴含其余货色,例如:缓存、文件类型、参数、申请类型、状态等。它是建设在传输层TCP协定之上的,TCP握手胜利之后,才能够进行网络数据传输。

HTTP/HTTPS

1. 什么是http协定?它是怎么样的?

http是TCP/IP协定应用层协定,次要负责数据或文本图片等内容的传输,它是建设在传输层TCP协定之上的。http分为申请报文和响应报文,从Web客户端发往Web服务器的HTTP报文称为申请报文(request message)。从服务器发往客户端的报文称为响应报文,报文分为:起始行、 首部字段、主体等;


2. http和https的区别?

http和https从字面的区别就是一个s,这个s就是SSL/TCL加密协议。说到加密协议就绕不开加密技术,在SSL/TCL加密协议中既有用到非对称加密,也有用到对称加密。SSL/TCL加密协议相当于是在应用层和传输层之间加了一层,可称为加密层。
大抵流程:客户端向服务器端索要加密证书获取公钥等证书信息;单方协商生成"对话密钥";单方采纳"对话密钥"进行加密通信。非对称加密保障"对话密钥"的平安传输,对称加密保障客户端和服务端对数据的加解密。


3. http网络缓存如何配置?

如果须要开启强缓存和协商缓存,可在服务端nginx web服务器进行对应的配置,开启对应的网络缓存。其余服务端web服务器也可配置。(配置细节网上一大堆)


4. 强缓存和协商缓存的区别?

强缓存:Cache-Control,罕用属性有max-age、no-cache、no-store等。max-age示意绝对工夫内的缓存,在这个绝对工夫内不会再去申请对应资源;no-cache示意不意味着不缓存,它的意思是在应用缓存资源之前,它必须通过服务器的查看;
no-store示意不缓存。
协商缓存:Last-modified 和 ETag,这两个相似,能够了解为文件标识。也能够将ETag(你抉择的版本ID)或者Last-modified日期增加到响应首部中。客户端下次获取资源时,他会别离通过If-None-Match(与ETage对应)和If-Modified-Since(与Last-Mofied对应)两个申请首部将值发送给服务器。如果服务器发现两次值都是对等的,就是返回一个HTTP 304。它们之间的区别:ETag 只有资源变动,它就会扭转;Last-modified 不辨认秒单位里的批改。
如何应用—————前端中保障HTML资源是最新的,设置如:max-age=300、ETag、Last-modified,当然也可思考应用no-cache、ETag、Last-modified配合。而CSS和JS找资源曾经被注入到HTML中,资源文件地址通常应用哈希值退出文件名中保障资源是最新,css和js文件可设置:max-age=31536000或last-modified 配合应用。


5. 理解http2.0嘛?为什么说http2.0更好?

http2.0基于二进制分帧层,http2.0能够在共享TCP连贯的根底上同时发送申请和响应。在http1.x中,是通过文本的形式传输数据,基于文本的形式传输数据存在很多缺点,文本的表现形式有多样性,因而要做到健壮性思考的场景必然有很多,然而二进制则不同,只有0和1的组合,因而抉择了二进制传输,实现不便且强壮。
为了保障http不受影响,那就须要在应用层(HTTP2.0)和传输层(TCP or UDP)之间减少一个二进制分帧层。在二进制分帧层上,http2.0会将所有传输的信息分为更小的音讯和帧,并采纳二进制格局编码,其中http1.x的首部信息会被封装到Headers帧,而Request Body则封装到Data帧。在传输中会共用一个TCP流(TCP连贯中的一个虚构通道,能够承载双向的音讯),不至于反复连贯。


参考:
书籍:HTTP权威指南
SSL/TLS协定运行机制的概述

前端框架

前端框架目前市面支流就是React和Vue,对于框架的应用和学习,后期倡议多翻翻文档,中期依据本人在应用过程中遇到的问题学习,前期就能够思考翻源码了。因为工作起因,我对react理解更多,所以分享次要就是React。
React和Vue作为前端框架在实质上做的是雷同的事,在浏览器和开发操作之间加了一个中间层,来进我的项目的辅助治理和开发。

React框架

1. JSX实质是什么,它和JS的关系是什么?为什么应用JSX?

JSX是类HTML的语法结构,本质是JS的语法扩张。它语法结构简洁,通俗易懂,对于研发效率和体验有大的晋升。


2. JSX背地的功能模块是什么,这个功能模块做了哪些事件?

JSX通过babel语法转换之后,理论就是通过React.createElement函数来创立React元素。createElement接管三个参数type类型,config配置,children子元素。通过createElement就可创立出虚构DOM对象。


3. react16.3新旧生命周期,隐没的旧生命周期有哪些?

去掉ComponentWillMountCompoentWillReceiveProps
降级为getDeicvedStateFromProps,保障生命周期更加繁多,更可控;去掉ComponentWillUpdate新增getSnapshotDeforeUpdate;


4. React团队为什么要去掉旧的生命周期函数?

React16+引入Fiber架构,Fiber会将一个大的更新工作拆解为多个小工作,而且它是可停止,可复原的。React16+生命周期被划分为rendercommit两个阶段。render阶段在执行过程中容许被打断,而commit阶段操作波及实在DOM渲染,是不可打断的。
ComponentWillMount
ComponentWillUpdate
ComponentWillReceiveProps
这些生命周期,它们都处于render阶段,而在Fiber架构中,render阶段会被打断,反复被执行。在这些生命周期可能习惯做的事件可能有:setState、异步申请、操作实在DOM等。而在Fiber异步渲染管制下,这些生命周期可能会导致十分重大的bug(例如在这些废除的生命周期中调用领取接口)。


5. React组件数据如何流动?实现数据通信的计划有哪些?

react是自上而下的单向组件数据流

1.父-子组件通过prop属性传递数据,子-父组件可通过函数;2.兄弟组件共享同一个父组件,达到兄弟组件通信;3.Context API实现全局通信;(目前还没试过)4.redux数据状态容,进行可预测的状态治理;5.公布/订阅模式实现任意组件通信;

6. 为什么是React Hooks?

绝对于Class组件,函数组件更加轻量,更加合乎UI=render(data)特点。同时在Fiber架构的加持下,Hooks的实现不是问题。配合函数组件的倒退,Hooks应运而生,从而是函数组件真正把数据和渲染绑定到一起。当然Hooks也还是存在局部有余:局部周期不存在;不能很好的消化“简单”,组件的拆分和组织是一个大的挑战,不易把握。


7. 为什么Hooks执行程序如此重要?

Hooks实质是链表。例如 应用useText、useState创立state时,hook创立的state会以单链表模式保留,更新时,函数组件从新调用,hooks会顺次遍历单链表,读取数据并更新,这一过程齐全依照创立时的程序来的。因而当更新时,地位一旦扭转,执行程序被替换,运行就会呈现bug。


8. 和谐(协调)和diff的关系或区别?

和谐指的是虚构DOM映射到实在DOM的过程。和谐过程并不能喝diff画等号。和谐是“使统一”的过程,而diff是“找不同”的过程,它只是“使统一”过程中的一个环节。(当然常说的和谐相干问题多半就是diff过程的)


9. react的diff逻辑和思路?

1.因为工夫付扎渡的起因,diff过程只针对同层的节点作比拟;2.对于同类型的组件,才有进一步比照的必要性;3.对于列表组件,通过key属性来维持节点的稳定性,防止总是生产新节点;

10. setState的工作流是怎么样的?

非并发(concurrent)模式:setState会呈现异步和同步的景象。在生命周期和合成事件中是同步,而在setTimeout、setInterval、DOM原生函数等函数中是同步的。那么这是为什么尼?在合成事件或生命周期执行时,批量更新的工作锁就被开启了,咱们所做的setState操作会被放入到批量更新队列中,直到函数执行完,批量更新的工作锁才会被敞开。批量更新的工作锁是一个同步操作,而一旦你在setTimeout函数应用setState,此时setTimeout函数回调会被放入下一个宏工作执行,而当setState执行时,批量更新的工作锁时敞开的,它就不会放入到批量更新队列中,而是间接执行。

并发(concurrent)模式:setState不会呈现异步和同步的景象。因为存在工夫切片,只有以后工夫片没有完结,仍旧能够将多个 setState 合并成一个,即便是在setTimeout中被调用。而对于超过以后工夫片的操作,会通过MessageChannel放入到下一个宏工作中继续执行。(MessageChannel接管音讯的机会比 Promise 所在的 microTask 要晚,然而早于 setTimeout)


11. Stack Reconciler栈和谐 有怎么样的局限性?

浏览器中Js线程和渲染线程是互斥的。这两个线程不能交叉执行,必须串行。而当Js线程长时间占用主线程,那么渲染线程的更新就不得不长时间的期待,这时就会导致页面卡顿。
Stack Reconciler栈和谐是一个同步递归过程,虚构DOM树diff算法遍历是深度优先遍历。因为它是同步的,不可在被打断。当解决结构复杂,体量宏大的虚构DOM树时,Stack Reconciler工夫会很长,认为这Js主线程长时间占用主线程,进而导致上述中说道的渲染卡顿/页面卡死。


12. 说一说Fiber架构?

特点:可中断、可复原、存在优先级。

 Scheduler ————> Reconciler ————> Renderer 更新优先级         找不同         渲染不同

Fiber架构模式下,每个更新工作会被赋予一个优先级。当然有工作A进入调度器,这个工作优先级更高,而Reconciler中已有工作B在执行,那么,Reconciler会将工作B终止,更高优先级的工作A被推入Reconciler。当A工作实现之后,新一轮调度会将之前中断的工作B从新推入Reconciler,持续它的渲染之旅。

render开始 ——————> (工作单元| 工作单元 | 工作单元) ——————> commit提交渲染

13. ReactDOM.render调用栈的初始化阶段、render阶段

初始化阶段:会创立root对象这个对象挂载_internalRoot属性,而_internalRoot也就是FiberRootFiberRoot的实质是一个FiberRootNode对象,其中蕴含current属性,current对象是一个FiberNode实例。current对象就是一个Fiber节点,并是Fiber树的头部节点;确定Fiber的优先级,联合优先级创立以后Fiber的update对象,并将其入队调度FiberRoot;接下来进入render阶段;(此时相当于只有一个Fiber头部节点)

render阶段:通过createWorkInProgress函数,创立rootFiber节点的正本workInProgress节点树(即current节点的正本节点),他们通过alternate相互援用;接着会触发beginWork函数,进而实现对新的Fiber节点的创立。循环遍历,组件元素Fiber会一直被创立(每个元素节点对应一个Fiber节点),直到创立到最初一个为止,此时Fiber树(单链表)根本实现;重点,此时曾经遍历到了单链表的最底部节点,而后会由下自上的顺次生成实在DOM节点,同时被它的父组件副作用链,这个副作用链也是一个单链表,直遍历到根节点,此时的根节点上的副作用链就蕴含的全副的DOM更新。那么剩下的只须要拿到root下的副作用链更新即可了。


参考:
修言 深入浅出搞定 React
React 架构的演变 - 从同步到异步
React 架构的演变 - 从递归到循环
React 架构的演变 - 更新机制
React 架构的演变 - Hooks 的实现

性能优化

可应用Chrome Lighthouse进行性能测评,依据测评后果也能够得出一些改良的点:
react框架层面能够做的优化方向外围点:缩小从新 render 的次数缩小计算的量,次要是缩小反复计算。有下列具体计划:

1. 拆分公共组件和业务组件,依据具体业务拆散,升高组件颗粒度;2. shouldComponentUpdate中拦挡非不要渲染;3. 对于简略的数据类型,可思考应用React.PureComponent;4. 函数组件思考应用React.meno,React.memo 与 React.PureComponent 十分类似;(版本React 16.6.0)5. React Hooks组件应用useCallback缓存函数,防止每次返回一个新的函数;(版本React v16.8)6. React Hooks组件应用useMemo缓存计算值;(版本React v16.8)

一个前端我的项目下通用的优化技巧:应用缓存、节流、压缩、按需加载、全局治理等办法或技巧。如下:

1. 防止频繁渲染更新,即便必须的状况下,也须要思考是否应用节流函数;2. 对于长列表页面,思考翻页加载、点击下一页或者虚构长列表,防止数据量过大,渲染卡顿;3. 对立管制我的项目中的定时器函数,防止定时器偷跑;4. 拆分Js文件,可思考按需加载,晋升加载速度;5. 保障首屏必要数据渲染,可减少过渡图片,晋升用户体验;6. 对于后端接口多余数据可思考荡涤数据,只保留必要数据;7. 防止过多的数据申请,可思考应用数据缓存,晋升用户体验;8. 对于大图思考CDN图片加载,也可思考图片懒加载;9. 防止应用过多css选择器嵌套;10. 代码文件gzip压缩等,服务器相干缓存配置;

以上更多的是各种技巧和准则,如果要晓得具体的规范,能够参考google为Web性能体现提供的文档developers.google.cn/Web Performance

设计模式

参考文章:
JavaScript设计模式