我的前端知识体系
2020-06-05 14:43:23 1 举报
AI智能生成
我的前端知识体系
作者其他创作
大纲/内容
前端体系
编程基础
计算机网络
七层框架
应用层
应用层的重要协议
FTP:用于文件传输、访问和管理
SMTP、POP3:用于电子邮件
HTTP:用于虚拟终端
DNS:查询服务和远程作业登录
http
报文结构
起始行
请求报文:方法+路径+http版本
响应报文:http版本+状态码+原因
头部
字段名不区分大小写
字段名不允许出现空格、下划线
字段名后面必须紧接冒号
空行
空行用来区分开头部和实体
如果在头部中间故意加一个空行,那么空行后的内容全部被视为实体
实体
请求方法
GET:通常用来获取资源
POST:提交数据
GET和POST的区别
从缓存角度,GET请求会被浏览器主动缓存下来,POST默认不会
从编码角度:GET只能进行URL编码,只能接收ASCII字符,POST没有限制
从参数角度:GET一般放在URL中,不安全。POST放在请求体中,更适合传传输敏感信息
从幂等性角度:GET是幂等的,POST不是
从TCP角度:GET请求会把报文一次性发出去,POST会分为两个TCP数据包。先发header部分,如果服务器响应100,再发body部分
HEAD:获取资源的元信息
PUT:修改数据
DELETE:删除资源
CONNECT:建立连接隧道,用于代理服务器
OPTIONS:列出可对资源实行的请求方法,用来跨域请求
TRACE:追踪请求-响应的传输路径
URL
scheme: 协议名
user:password:登录主机时的用户信息
host:port: 主机名和端口
path: 请求路径
query: 查询参数
URI引入编码机制,将所有非ASCII码字符和界定符转为十六进制字节值,然后在前面加%
HTTP状态码
1xx:表示目前是协议处理的中间状态,还需要后续操作
2xx:表示成功状态
3xx:表示重定向状态,资源位置发生变动,需要重新请求
4xx:请求报文有误
5xx:服务器端发生错误
https
传统RSA版
浏览器向服务器发送client_random和加密方法列表
浏览器向服务器返回sever_random、选择的加密方法和数字证书
浏览器验证数字证书和签名,从证书中提取中公钥,通过验证后根据client_random和server_random生成pre_random,用公钥加密后传给服务器
服务器用公钥私钥解密或者pre_random
浏览器分别用自己的client_random、server_random、pre_random联合生成secret(RSA加密)
之后的传输都使用secret作为密钥进行加解密
TSL1.2
浏览器向服务器发送client_random、TSL版本、加密套件列表
服务器接收到之后返回server_random、server_params、确认TSL版本,使用的加密套件列表、服务器使用的证书
客户端验证证书和签名,如果通过,传递client_params参数给服务器。然后客户端根据server_params和client_params用ECDHE算法加密得到pre_random
客户端根据client_random、server_random和pre_random用伪随机数函数计算出secret
服务端也根据server_random、client_random用ECDHE算法得到pre_random
服务端也根据client_random、server_ramdom和pre_random用伪随机数函数计算出secret
之后的传输都使用secret作为密钥进行加密
http2
http3
表示层
会话层
传输层
UDP协议
无连接
最大努力交付
面向报文,适合一次传输少量数据
没有拥塞控制,适合很多实时应用,比如视频会议(网速情况好的前提下)
首部只有8字节
TCP协议
特点
面向连接
可靠有序,不丢不重
全双工通信
面向字节流
建立连接(3次握手)
客户端发送一个数据包告诉服务器要建立连接
服务器收到该数据包后,为该TCP连接分配缓存和变量。然后返回一个确认报文
客户端给服务器返回一个确认
释放连接(4次挥手)
客户端发起请求,请求断开连接
服务器收到客户端的请求断开连接的报文之后,返回确认信息
当服务器也没有了可以传的信息之后,给客户端发送请求结束的报文
客户端收到FIN=1的报文之后,返回确认报文。发送完毕之后,客户端进入等待状态,等待两个周期后关闭。服务器收到最后的确认报文后立即关闭
为什么连接的时候是三次握手,关闭的时候要四次
为什么不能用两次握手进行连接
TCP拥塞控制
慢开始
拥塞避免
快重传
快恢复
网络层
网络层的主要任务是将分组从一台主机转移到另一台主机,从而提供了主机到主机的通信服务和各种形式的进程到进程的通信
分组交换
数据报
数据链路层
主要功能
封装成帧
透明传输
差错控制
差错纠正
流量控制
物理层
数据结构与算法
设计模式
运行环境
V8引擎
垃圾回收
内存限制
内存结构
栈内存
堆内存
新生代
老生代
大对象区
代码区
map区
垃圾回收策略
新生代: Scavenge算法
晋升
Mark-Sweep(标记清除)
Mark-compact(标记整理)
优化
增量标记
延迟清理
增量式整理
如何避免内存泄漏
尽可能少的创建全局变量
手动清除定时器
少用闭包
清除DOM引用
弱引用(weakMap、weakSet)
浏览器
渲染流程
处理用户输入
执行js(事件循环机制)
渲染开始
处理事件回调
requestAnimationFrame
parse HTML 生成DOM树
Recalc Styles 生成CSS规则树
layout 生成Render树
update layer tree 创建层叠上下文和元素层级顺序
paint 开始绘制
Compisite 为硬件加速的元素创建合成层
光栅化
Frame End 将光栅化后的纹理(tiles)提交给GPU
Frame Ships GPU绘制
多进程架构
browser主进程
第三方插件进程
GPU进程
渲染进程
GUI渲染线程
js引擎线程
事件触发线程
定时触发器线程
异步http请求线程
服务器
node
express
koa
mongodb
nginx
h5
适配
rem
vw/vh
dp
PWA
App
原生开发
混合开发
hybrid
jsbridge
JS 向 Native 发送消息 : 调用相关功能、通知 Native 当前 JS 的相关状态等
注入API
拦截 URL SCHEME
Native 向 JS 发送消息 : 回溯调用结果、消息推送、通知 JS 当前 Native 的状态等
Bridge使用方式
微信
微信小程序
微信公众号
微信小游戏
桌面程序
桌面PWA
electron
前端基础
html
canvas
css
flex
flex-basis
flex-grow
flex-shrink
css3动画
2D转换
transform
translate(平移)
rotate(旋转)
scale(缩放)
skew(倾斜)
matrix(矩阵)
transform-origin
3D转换
transform
perspective
transform-style
perspective-origin
backface-visibility
过渡
transition
transition-property
transition-delay
transition-duration
transition-timing-function\t
关键帧动画
@keyframes
animation
animation-name
animation-duration
animation-timing-function
animation-delay
animation-iteration-count
animation-direction
animation-fill-mode
animation-play-state
JavaScript
数字
字符串
对象
原型
prototype
__proto__
constructor
继承
原型链
原型链继承
重写原型会导致默认的constructor丢失,需要手动指定
问题一:引用类型的原型属性会被所有实例对象共享
问题二:在创建子类型的实例时,不能向超类型的构造函数中传递参数
构造函数继承
可以在子类型构造函数中向超类型构造函数传递参数
问题:不能继承父类prototype上的属性和方法
问题:每次子类实例化都要执行父类函数,重新声明父类this里的方法,导致方法无法复用
组合继承
将原型链和借用构造函数的技术组合到一块
问题一:超类构造函数调用两次
问题二:在子类的原型上添加了不必要的属性
原型式继承
适用于继承单个对象
问题:引用类型的原型属性会被所有实例对象共享,存在篡改的风险
问题:无法传参
寄生继承
创建一个仅用于封装继承过程的函数,改函数在内部已某种方式类增强对象,最后返回对象
封装的继承过程的函数无法复用
寄生组合式继承
使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型
超类构造函数只调用了一次
子类原型对象上没有多余的方法
寄生组合式继承是目前最理想的继承方式
es6 extends
原理和寄生组合式继承一样
ES5的继承实质是先创建子类的实例对象this,然后将父类的方法添加到this上。
ES6的继承实质是先将父类实例对象的方法和属性加到this上面,然后在用子类的构造函数修改this。
ES5继承不能继承内置对象,ES6可以
深拷贝
JSON.parse(JSON.stringify(obj))
递归拷贝属性
Proxy
类
super
作为函数时表示父类的构造函数,但是返回的是子类的实例
作为对象时,在普通方法中指向父类的原型对象,在静态方法中指向父类
在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例
如果通过super对某个属性赋值,此时的super指向this,赋值的属性会变成子类实例的属性
在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例
Object.getPrototypeOf() 用于从子类上获取父类
数组
遍历
for
for...of
forEach
map
entries
keys
values
函数
闭包
高阶函数
柯里化
箭头函数
尾调用优化
尾递归
改写递归函数
在尾递归函数之外,再提供一个正常形式的函数。
采用 ES6 的函数默认值
尾递归优化的实现
函数式编程
模块化
esModule
自动采用严格模式
编译时就能确定模块的依赖关系,以及输入和输出的变量
编译时加载
export
export语句输出的是接口,与其对应的指是动态绑定关系
export命令只能出现在模块顶层作用域,如果出现在块级作用域就会报错,因为块级作用域无法做静态优化,违背了esModule设计的初衷
export default 命令用于指定模块的默认输出。一个模块只能有一个默认输出
export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句
import
import命令输入的变量都是只读的,变量不允许修改,但如果是对象,可以修改其属性。修改会影响到其他模块
import名称具有提升效果,会提升到整个模块的头部,首先执行。本质是import命令是在代码运行之前的编译阶段执行
import是静态执行,不能使用表达式和变量这些只有在运行时才能得到结果的语法结构
import 'xxx' 仅执行xxx模块,不会输入任何值
import 语句是Singleton模式,import多次同一个模块,只会执行一次
import * as testModule from 'xxx' 表示整体加载xxx模块,所有输出的值都在testModule上
浏览器加载esModule
script标签加type=\"module\"
异步加载,等页面渲染完毕再执行脚本,等同于打开了defer属性
打开async属性后,只要加载完成,渲染引擎就会中断渲染立即执行,执行完成后再恢复渲染
Node.js加载esModule
.mjs文件总是以ES6模式加载,.cjs文件总是以CommonJs模式加载
.js文件的加载模式取决于package.json里type字段
必须使用import加载.mjs文件,使用require会报错
esModule模块加载CommonJs模块
import命令加载CommonJs模块,只能整体加载,不能只加载单一的输出项
使用Node.js内置的module.createRequire()方法
NodeJs的内置模块可以整体加载,也可以加载指定的输出项
CommonJs模块加载esModule模块
CommonJs的require命令不能加载ES6模块,只能使用import()方法加载
CommonJs
运行时才能确定模块的依赖关系以及输入输出的变量
运行时加载
require命令第一次加载模块,就会执行整个模块,然后在内存中生成一个对象
多次require一个模块,只会在第一次加载时运行一次,后续的加载直接返回第一次的运行结果,除非手动清除缓存
esModule和CommonJs的差异
CommonJs输出的是值的拷贝,esModule输出值的引用
CommonJs模块是运行时加载,esModule模块是编译时输出接口
循环加载
esModule模块中循环加载时,需要自己保证真正取值的时候能取到值
CommonJs模块中循环加载时,只输出已经执行的部分,未执行的部分不会输出
异步处理
回调函数
promise
并发控制
generator
async/await
Symbol
正则表达式
JSON
JSON.stringify()
undefined、任意的函数以及Symbol作为对象属性值时JSON.stringify()跳过对他们的序列化
undefined、任意的函数以及Symbol作为数组的元素时,JSON.stringifyIO将会把他们序列化为null
undefined、任意的函数以及Symbol作为单独的值进行序列化时,都会返回undefined
转换值如果有toJSON()函数,该函数返回什么值,序列化结果就是什么值,并且忽略其他属性的值
NaN和Infinity格式的数值及null都会被当做null
布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值
其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性。
对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。
所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。
第二个参数replacer
replacer是一个函数:类似数组的map方法,对每一个属性值都会执行一次该函数
replacer是一个数组:数组的值代表将被序列化成JSON字符串的属性名
第三个参数:序列化之后的缩进,可以是数字和字符串
JSON.parse()
事件循环机制
宏任务队列 macro
setTimeout
setInterval
script
I/O
UI渲染
微任务队列 micro
new Promise().then()
MutationObserver
6个阶段
timers
I/O callbacks
poll (入口)
check
close callbacks
11版本之前。宏任务执行完后,如果下一个宏任务已经在队列中了,就执行下一个宏任务。否则执行微任务
11版本之后。和浏览器一样,执行完一个宏任务后就执行微任务队列
process.nextTick() 在所有微任务执行之前执行
浏览器和node的区别
浏览器的微任务是在每个宏任务执行之后执行
node中的微任务是在不同阶段之间执行
vue
原理简述
变化侦测
Object变化侦测
Data通过Observer转化成getter/setter的形式来追踪变化
当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到依赖中。以来存储在Dep中
当数据发生了变化时,会触发setter,从而向Dep中的依赖(Watcher)发送通知。
Watcher接收到通知后,会向外界发送通知,进而触发试图更新或者触发回调函数
Array变化侦测
在getter中收集依赖,在拦截器中触发依赖
只能拦截原型上的方法,无法拦截数组特有的语法
虚拟DOM
vue中的虚拟dom
vnode
patch
patch流程
创建节点
删除节点
更新节点
更新子节点
创建子节点
移动子节点
删除子节点
优化策略
快捷查找
key
模板编译
解析器
优化器
代码生成器
常用API的原理
vm.$nextTick()
语法
vue-router
hash模式
history模式
vuex
react
jsx
组件
class组件
class组件的不足
状态逻辑难复用,元素层级冗余
各生命周期中的逻辑趋向复杂难以维护
this指向问题
函数组件
hooks
useState
每次渲染都是独立的闭包
如果新的 state 需要通过使用先前的 state 计算得出,那么可以将回调函数当做参数传递给 setState
initialState 参数只会在组件的初始化渲染中起作用,后续渲染时会被忽略
使用 Object.is 来比较新/旧 state 是否相等
如果你修改状态的时候,传的状态值没有变化,则当前不重新渲染
useState 不会自动合并更新对象,更新时是直接提替换
子主题
Fiber
工程化
打包
webpack
webpack原理
核心概念
entry:入口
module: 模块,webpack中一切皆模块,一个模块对应一个文件,webpack从entry开始递归找出所有依赖的模块
chunk:代码块,一个chunk由多个模块组成,用于代码合并与分割
loader:模块转换器,用于把模块原内容按照需求转成新内容
plugin:扩展插件,在webpack构建流程中的特定时机会广播出对应的事件,插件监听事件的发生,在特定时机做对应的事情
流程概括
初始化参数:从配置文件和shell语句中读取与合并参数,得到最终参数
开始编译:用参数初始化compiler对象,加载所有配置的插件,执行compiler对象的run方法开始执行编译
确定入口:根据entry找出所有的入口文件
编译模块:从入口出发,调用loader对模块进行编译,再找出依赖的模块进行编译,递归找出依赖的依赖,直到所有依赖的文件都被编译
完成编译:经过loader编译后,得到每个模块被编译后的最终内容以及它们之间的依赖关系
输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,再把chunk转换成单独的文件加入到输出列表
输出完成:在确定好输出内容后,根据配置的输出路径和文件名,把文件内容写入到文件系统
速度优化
通过 speed-measure-webpack-plugin 测量 webpack 构建期间各个阶段花费的时间
优化解析时间,开启多进程打包
thread-loader
HappyPack(停止维护,不推荐)
优化压缩时间
webpack3使用ParallelUglifyPlugin做多进程压缩
webpack4使用terser-webpack-plugin做多进程压缩
优化搜索时间- 缩小文件搜索范围
通过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件
resolve.modules 用于配置 webpack 去哪些目录下寻找第三方模块
resolve.alias 配置项通过别名来把原导入路径映射成一个新的导入路径,减少耗时的递归解析操作。
module.noParse 配置项可以让 Webpack 忽略对部分没采用模块化的文件的递归解析处理
体积优化
使用webpack-bundle-analyzer可视化打包体积
引入 DllPlugin 和 DllReferencePlugin
外部引入模块(CDN)
按需异步加载模块
splitChunk分包
对动态引入模块的处理
__webpack_require__.e加载
webpackJsonp触发resolve
rollup
持续集成
自动化测试
单元测试 unit test
jest
vue组件自动化测试
集成测试 e2e test
cypress
web安全
跨站脚本攻击(XSS)
反射型
DOM型
存储型
防范手段
content Security Policy
禁止加载外域代码,防止复杂的攻击逻辑
禁止外域提交,网站被攻击后,用户的数据不会泄漏到外域
禁止内联脚本执行
禁止未授权的脚本执行
输入内容限制
Cookie设置Http-only防止被窃取
跨站请求伪造(CSRF)
在关键操作处添加验证码
使用Referrer判断请求来源
使用token
Cookie设置Samesite属性
点击劫持
性能优化
0 条评论
回复 删除
下一页