h5+c3部分
什么是mvc mvvm
mvc是一种代码架构设计模式,前端中的mvc最主要的作用就是将视图和数据模型进行分离
Model:数据层(存数据、改数据)
View:视图层(页面展示和dom的操作)
Controller:控制视图层和数据层的关联,主要通过监听dom事件
mvvm整体和mvc差不多
最大的区别就是mvc是单向的,而mvvm是双向的,并且是自动的,也就是数据发生变化自动同步视图,视图发生变化自动同步数据,
如今主流的web框架基本都采用的是MVVM模式,为什么放弃了MVC模式,转而投向了MVVM模式呢。在之前的MVC中我们提到一个控制器对应一个视图,控制器用状态机进行管理,这里就存在一个问题,如果项目足够大的时候,状态机的代码量就变得非常臃肿,难以维护。还有一个就是性能问题,在MVC中我们大量的操作了DOM,而大量操作DOM会让页面渲染性能降低,加载速度变慢,影响用户体验。最后就是当Model频繁变化的时候,开发者就主动更新View,那么数据的维护就变得困难。世界是懒人创造的,为了减小工作量,节约时间,一个更适合前端开发的架构模式就显得非常重要
什么是BFC
bfc是块级格式上下文,它会形成一个独立的渲染区域,在这个区域内外元素互不影响
1、BFC是一个独立的布局环境,BFC内部的元素布局与外部互不影响;
2、可以通过一些条件触发BFC,从而实现布局上的需求或解决一些问题;
形成条件:开启float,overflow:hidden,position:fix和absolute,display:flex,inline-bock
应用场景:清除浮动,外边距重叠,浮动高度塌陷
header里 meta 标签的作用
编码格式:charset
使用IE浏览器最高内核Edege
viewport 视口适配用的
垂直居中
flex
display: flex;
align-items: center;
justify-content: center;
grid
display: grid;
place-items: center;
postation
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
前端响应式布局是什么
响应式布局可以为不同终端的用户提供更加舒适的界面和更好的用户体验
js部分
JS实现异步的方法是什么?
1、利用setTimeout;2、利用setImmediate;3、利用requestAnimationFrame;4、通过监听“new Image”加载状态来实现;5、通过监听script加载状态来实现;6、利用Message等等。 7.promise
普通函数 vs 箭头函数,它们有何不同?
- 箭头函数比普通函数更加简洁 可以省略括号
- 箭头函数没有自己的this
- this指向外部
- call()、apply()、bind()等方法不能改变箭头函数中this的指向
- 箭头函数不能作为构造函数使用
- 箭头函数没有自己的arguments ,没有prototype
什么是事件流
描述事件触发的顺序,一般包括事件捕获,目标阶段,事件冒泡
事件委托
事件委托是绑定事件的一种技巧,就是利用事件冒泡(内到外),把原本应该绑定到子元素上的事件委托到父元素上,让父元素来监听事件
最典型的应用场景就是动态绑定事件,在ul里的每一个li绑定一个click事件,就可以用事件委托,把click事件委托给ul来做,这一段话再ul追加li,就能动态的绑定click
优点:可以大量节省内存占用,减少事件注册
js运行机制
js是单线程语言,也就是说在执行任务时会,一个一个排队执行。
事件循环(Event Loop)
主线程会先执行同步任务,碰到异步任务会放到事件表格(Event Tabel),当满足触发条件,会把异步任务从event tabel注册到事件队列(Event Queue),主线程执行完同步任务,空闲时去执行Event Queue的异步任务,异步任务分为微任务和宏任务
在执行异步任务时,先执行微任务,在执行宏任务
js数据类型
string、number、boolean、null、undenfind、symbol、bigint、array、object
bigint:在js中number的最大安全整数253-1,当比较253==2^53+1是true bigint能表示超过最大安全整数的数字
什么是原型?
任何一个函数都有一个prototype
属性,它默认指向一个Object空对象(即为原型对象)
原型对象中有一个属性constructor
,它指向函数对象
js中的继承
原型链继承
构造函数继承
组和继承
寄生组合继承
class继承
作用域
es6之前:全局作用域,函数作用域,
es6:引入块级作用域
作用域链:当我们在作用域内部访问一个变量的时,会在当前作用域找,如果没找到会去外层作用域也是父级作用域去找,一直找到全局作用域,我们把这种作用域一层一层嵌套的机制,称为作用域链
什么是闭包
闭包就是 有权访问另外一个函数中变量的函数,他可以延长了函数中变量的生命周期,列如:我们定义一个函数,正常情况下,函数外部是不能拿到函数内作用域中的变量的,而闭包就可以做到在函数外部读取到这个变量
说说es6+
- let const symbol bigint 模板字符串 结构表达式 箭头函数 promise proxy 操作符 … ?.(可选链) ??(空值合并) &&= ||=(逻辑赋值)
- object api
Object.keys()
Object.values()
Object.entries()
Object.fromEntries()
Object.is()
Object.create()
Object.freeze()
- Array api
let arr = [1, 2, 3, 1,99 , [(77)[11]]];
Array.isArray();
Array.from();
- `push`:数组尾部添加元素
- `unshift`:数组头部添加元素
- `pop`:数组尾部移除元素
- `shift`:数组头部移除元素
arr.forEach() //return 不会打断
arr.fill(val,start,end)
arr.at();
arr.concat();
arr.includes();
arr.indexOf();
arr.slice(); //start end 不改变原数组
arr.splice(); //start 个数 没有第三个参数就是删除,有就是替换,改变原数组
arr.some() //方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值。
arr.every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
arr.filter(); //返回满足条件的所有值
arr.find(); //返回满足条件的第一个值
arr.map();
arr.reduce();
/**
* 第一个参数是回调函数
* (第一个参数:上一次回调函数返回值,后三个参数和map一样)
* 第二个参数是初始化回调函数第一个参数
*
*/
arr.flat(deep); //打平数组 可以传0去除空值
// 判断数组
Array.isArray(arr)
arr instanceof Array
Object.prototype.toString.call(arr)
// 判断数组包含某个值
arr.includes(99)
arr.indexOf(99)
arr.filter(item=>item==999)
setImmediate
weakRef
weamap
promise api
- Promise是JS进行异步编程的新的解决方案
Promise.reject();
返回一个状态为失败的promise对象,内容为传入的参数
Promise.resolve();
参数为非promise 返回一个成功状态的promise 内容为传入的参数
参数为promise,返回这个参数
Promise.all();
参数为promise数组 所有的成功则返的状态成功,结果为所有成功结果的数组
只要一个失败,返回这个失败promise
Promise.race();
参数为promise数组,返回第一个改变状态的promise失败或者成功
Map和Object的区别
1.map的key可以是如何东西 obj的key只能是string或者symbol
2.map有size直接获取键值对数量
3.map是有序的,根据set的顺序,obj按照规律排序
4.map for of 遍历,,obj for in 遍历
0.1+0.2!=0.3
数字在计算机中用的是二进制表示,进行运算时会把0.1换算成二进制在计算,换算二进制时,当表示0.1,0.2这种浮点数时,对于二进制是一个无限循环的数只能准确表示2的-1次方的浮点数,,所以0.1+0.2会精度缺失
什么是跨域?如何解决
跨域就是违反了浏览器的同源策略(协议,域名,端口号不同),同源策略对js限制,一个域下的js脚本不允许在另外一个域执行
解决方式
jsonp:
JSONP的做法是:当需要跨域请求时,不使用AJAX,转而生成一个script元素去请求服务器,由于浏览器并不阻止script元素的请求,这样请求可以到达服务器。服务器拿到请求后,响应一段JS代码,这段代码实际上是一个函数调用,调用的是客户端预先生成好的函数,并把浏览器需要的数据作为参数传递到函数中,从而间接的把数据传递给客户端
JSONP有着明显的缺点,即其只能支持GET请求
cors
cors ----Access-control-allow-origin 😗
proxy:代理
nignx:
ajax和axios区别
都是对原生XHR的封装
JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理
axios 它是Promise的实现 体积也较小。
支持 Promise API 回调地狱
客户端支持防止CSRF
(这个支持防止CSRF是怎么做到的,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。)
onclick与addEventListener区别
1.onclick事件在同一时间只能指向唯一对象
2.addEventListener给一个事件注册多个listener
3.可以控制冒泡捕获
TS与JS区别、优势
概述:TS是JS的超集,JS有的Ts都有,
类型
- 元组 Tuple :元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
- 枚举 enum:类型是对JavaScript标准数据类型的一个补充。
- any
- Never : never类型表示的是那些永不存在的值的类型。
- unknown
泛型
区别:
JS变量是没有类型的,即a=1,可以 a=‘111’
Ts有明确的类型(即:变量名:number(数值类型))
静态类型语言
1、TypeScript 引入了 JavaScript 中没有的“类”概念
2、TypeScript 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中。
3、js没有重载概念,ts有可以重载
4、ts对比js基础类型上,增加了 void/never/any/元组/枚举/以及一些高级类型
React
function component 和 class component 的区别?
语法不同
functional component 语法更简单,只需要传入一个props参数,返回一个react片段。
class component 要求先继承 React.Component,然后创建一个 render 方法,在 render 里面返回 react 片段。
state 状态
function component 只是一个普通的函数,所以不可以使用 this.state , setState()。这也是它被叫做无状态组件的原因。
所以如果一个组件需要用到状态的时候要用 class component。
生命周期
function component 不具有生命周期,因为所有的生命周期钩子函数均来自于 React.Component。
所以当一个组件需要生命周期钩子的时候我们也需要 class component。
为什么要用 function component?
function component 和 class component 比起来缺少那么多功能为什么还要用function componet?
function component 更易于编写阅读和测试
代码量更少,上手容易
因为没有状态,可以更好的实现容器和表现的分离,可以只负责表现层的逻辑,不用考虑因为复杂的逻辑去改变状态从而带来的麻烦,有利于代码复用。
react团队提倡使用
为什么要用 class component?
虽然function component 有很多好处,但是有些时候class component 还是不可替代的。
当需要实现一些容器组件的时候,需要改变内部状态来实现组件的改变的时候
当需要用到生命周期钩子函数实现一些功能的时候
当我们需要提升性能时,性能是一个很重要的问题,有些时候我们需要减少组件的渲染次数,我们就需要在组件内部用shouldComponentUpdate 方法来去判断,或者继承React.PureComponent 类(自动调用shouldComponentUpdate)来实现 state 和 props 的浅比较进行判断组件是否重新渲染。
hook好处
react有类组件,有函数组件,而函数组件是没有状态,跟生命周期这个概念的。而hook刚好能够弥补这缺陷。像,useSate,useEffect配合使用,它就有模拟生命周期的感觉,初始化,挂载,更新,卸载的感觉。
代码复用变的更简单
不用记很多生命周期方法
hooks 不需要使用像 componentWillMount 等这类生命周期钩子,没有那么多的限制,通过一个 useEffect hook 就能一次实现 3 个生命周期的功能,这对开发者来说十分的友好。
采用 hooks 不再需要时刻关注 this 指向的问题,在类式组件中,我们需要时时刻刻地关注着 this 的指向,生怕哪里指错了导致出了问题
hooks 最大的好处就是组件的复用,对于每一个使用该组件的地方,就会开辟一个独立的内存空间,就像是在调用函数一样,十分的简单
代码的可读性强,我们不需要专门使用生命周期函数就能实现功能的聚合,更加方便阅读和代码的维护
hooks 底层实现已经帮助我们优化了很多的代码,我们只需要在使用 hooks 时,避免组件的重复渲染,适当控制渲染次数即可做到很好的优化,同时 hooks 也提供了类似于 useMemo useCallback 这样的 hook 来给我们做性能优化
因此我觉得 hooks 在写法上、可读性上、可复用性、性能上(大部分情况)都优于类式组件
React 性能优化
- React 性能优化的理念的主要方向就是这两个:
减少重新 render 的次数。因为在 React 里最重(花时间最长)的一块就是 reconction(简单的可以理解为 diff),如果不 render,就不会 reconction。 - 减少计算的量。主要是减少重复计算,对于函数式组件来说,每次 render 都会重新从头开始执行函数调用。
虚拟dom
为什么操作 dom 性能开销大 :
并不是查询 dom 树性能开销大,
原因:
- dom树的实现模块 和 js 模块 是分开的,这些跨模块的通讯增加了成本。
- dom 操作引起的浏览器的回流和重绘,使得性能开销巨大。
。
虚拟 dom 是通过遍历查询 dom 树的方式找到需要修改的 dom 然后修改样式行为或者结构,来达到更新 ui 的目的。
这种方式相当消耗计算资源,因为每次查询 dom 几乎都需要遍历整颗 dom 树,如果建立一个与 dom 树对应的虚拟 dom 对象( js 对象),以对象嵌套的方式来表示 dom 树,那么每次 dom 的更改就变成了 js 对象的属性的更改,这样一来就能查找 js 对象的属性变化要比查询 dom 树的性能开销小。
虚拟DOM是:用JS来模拟一颗 DOM 树,放在浏览器内存中
当你要改变时,虚拟 DOM 使用 diff 算法进行 新旧虚拟 dom 的比较将修改了的更新到实际的 DOM 树,减少了 DOM 操作
生命周期
Redux 工作流
mobx工作流
类组件的setstate和函数组件usestate的有什么不同
正常事件同步流中,click事件中 异步执行
多次执行setState和useState的set函数,组件只会重新渲染一次,
同时setState会进行state的合并,但是useState中的set函数做的操作,内部有个防抖的优化
webpack
暂无
浏览器
五层协议
各层作用
1,物理层;其主要功能是:主要负责在物理线路上传输原始的二进制数据。
2、数据链路层;其主要功能是:主要负责在通信的实体间建立数据链路连接。
3、网络层;其主要功能是:要负责创建逻辑链路,以及实现数据包的分片和重组,实现拥塞控制、网络互连等功能。
4、传输层;其主要功能是:负责向用户提供端到端的通信服务,实现流量控制以及差错控制。
5、应用层;其主要功能是:为应用程序提供了网络服务。
状态码
1.1 状态码分类
1xx - 服务器收到请求。
2xx - 请求成功,如 200。
3xx - 重定向,如 302。
4xx - 客户端错误,如 404。
5xx - 服务端错误,如 500。
1.2 常见状态码
200 - 成功。
301 - 永久重定向(配合 location,浏览器自动处理)。
302 - 临时重定向(配合 location,浏览器自动处理)。
304 - 资源未被修改。
403 - 没权限。
404 - 资源未找到。
500 - 服务器错误。
504 - 网关超时。
HTTPS和HTTP有什么区别?
1.传输信息安全性不同
http协议:是超文本传输协议,信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。
https协议:是具有安全性的ssl/tls加密传输协议,为浏览器和服务器之间的通信加密,确保数据传输的安全。
http请求无状态
SSL协议是位于应用层和传输层之间
2.连接方式不同http协议:http的连接很简单,是无状态的。https协议:是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议。 对称?非对称?
3.端口不同 http端口是80。https端口是443.
4.证书申请方式不同https协议:需要到ca申请证书
http请求无状态 那么怎么判断用户身份
sessionID
http 1.0 ,1.1, 2区别
HTTP1.0和HTTP1.1的一些区别
- 缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
- 长连接,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,HTTP1.0每次请求都要创建连接的缺点。
HTTP2.0和HTTP1.X相比的新特性 - 新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
- 多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
- header压缩, header带有大量信息,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
xss跨站脚本攻击
xss漏洞从本质上是将数据注入到静态代码中(如html和js等),当浏览器渲染html时就会触发注入的脚本引发xss攻击。
如何避免Xss?
CSRF跨站请求伪造攻击
CSRF避免?
同源检测
CSRF Token
浏览器本地储存有哪些?sessionStorage与localStorage、Cookie有何区别
Cookie :Cookie主要是由服务器生成,通过response响应头的set-Cookie字段进行设置,(且Cookie的内容自动在请求的时候被传递给服务器),主要记录客户端状态,保存用户登录状态,分辨两个请求是否来自同一个浏览器,
webStorage
indexDB:indexedDB 就是浏览器提供的本地数据库,它可以被网页脚本操作,IndexedDB 允许储存大量数据,提供查找接口,还能建立索引
Web SQL 不建议使用,已废弃
post和get区别
GET - 从指定的资源请求数据,参数url可见;。 POST - 向指定的资源提交要被处理的数据。 GET产生一个TCP数据包;POST产生两个TCP数据包。 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
get请求是可以缓存的
post请求不可以缓存
http缓存
第一次请求 响应头 cache-control 设置缓存时间