速记一
1.H5新增特性有哪些?
语义化标签、音视频(audio、video) canvas/WebGL 拖拽释放 (Drag drop) API history API requestAnimationFrame Geolocation API webSocket web存储localStorage SessionStorage(当前会话期有效) 表单控件 calendar date time email
2. HTTP状态码
- 403 ---> 服务器拒绝客户端的请求资源 (例如国内请求GPT)
- 404 ---> 客户端请求的资源不存在
- 304 ---> 客户端缓存依然有效,可以直接使用缓存数据而不需要再次请求服务器 客户端向服务器请求资源时,服务器会在响应头包含一个Last-Modified或者ETag
- 1xx: 请求已接受
- 2xx: 成功接受
- 3xx: 重定向 重定向会增加请求的延迟和网络流量
- 4xx: 重定向会增加请求的延迟和网络流量
- 5xx: 服务端错误
3. 语义化优点
- 代码结构清晰,易读
- 利于开发和维护
- 有利于SEO
4. 304的过程
缓存过期后向服务器发请求严重缓存是否有效,有效就返回304 浏览器第一次发起请求时(请求头中没if-Modified-since), server会在响应中告诉浏览器这资源最后修改的时间Last-Modified, 当再次请求资源时,浏览器会询问server这个资源有没有被修改 若无,则304
5. 数组常用方法
js
// join 将数组中的所有元素转化为字符串并连接起来 返回一个新的字符串
var arr = ['apple','banana','orange'];
arr.join('-'); // apple-banana-orange
// push 给数组中添加一个元素 (修改原数组)
const arr = [1, 2];
const length = arr.push(3, 4); // 4
console.log(arr); // [1, 2, 3, 4]
// pop 删除原数组最后一项,并返回删除元素的值 修改原数组)
arr.pop(); // [1,2,3]
// shift 删除数组头部第一项,并返回删除元素的值;
arr.shift(); // [2,3]
// unshift 在数组头部位置添加一项 修改原数组)
arr.unshift(44); // [2,3,44]
// slice(start,end) 截取出数组中的部分元素 不包含end
const as = [1,2,3,4,5];
as.slice(1,4); // [2,3,4]
// splice(start,deleteCount,item) 从start位置开始删除deleteCount个元素 添加item 修改原数组)
as.splice(1,2,33); // [2,33]
as.splice(1,3); // start位置开始 删除3个元素
// fill(value, start, end) 使用特定值填充数组中的一个或多个元素(修改原数组) 不包含end
const nusm = [1,2,3,4,5];
nums.fill(0,1,4); // [1,0,0,0,5];
// filter():过滤,数组中的每一项运行给定函数,返回满足过滤条件组成的数组
const arr = [1,2,3,4,5];
arr.filter((item)=>item%2 === 0) ; [2,4];
// concat():可以将两个数组合并在一起,如果是使用ES6语法也可以用扩展运算符…来代替
const a1 =[1,'abc'];
const a2 = [2,'kos'];
const newArr = a1.concat(a2);// [1,'abc',2,'kos'];
// indexOf():返回当前值在数组中第一次出现位置的索引
const que = [1,2,3,4,5];
const index = que.indexOf(3); // 索引为2
// lastIndexOf():返回查找的字符串最后出现的位置,如果没有找到匹配字符串则返回 -1。
// every() 判断数组中每一项是否都符合条件
// some():判断数组中是否存在满足的项
// includes():判断一个数组是否包含指定的值
const llod = [1,2,3,4,5];
const hee = llod.includes(3); // true
// sort(orderfunction):按指定的参数对数组进行排序(修改原数组)
// reverse():将数组反序(修改原数组)
// forEach():循环遍历数组每一项(没有返回值)
// map():循环遍历数组的每一项(有返回值)
// copyWithin(): 从数组的指定位置拷贝元素到数组的另一个指定位置中(修改原数组)
// find(): 返回第一个匹配的值,并停止查找
// findIndex() 返回第一个匹配的索引 并停止查找
// toLocaleString()、toString():将数组转换为字符串
// flat()、flatMap():扁平化数组
const newFlas = [1,[2,3],[3,[4,5]]];
function faltten(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
console.log(faltten(newFlas));
// entries() 、keys() 、values():遍历数组
6. CSS选择器优先级
- 选择器
- id选择器
- 类选择器
- 属性选择器
- 伪类选择器
- 标签选择器
- 相邻选择器
- 子选择器
- 后代选择器
- 通配符选择器
- 优先级 !import > 行内样式 > id选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认
7. 强缓存和协商缓存
- 强制缓存
什么是强制缓存? --> 向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。 原理 当第一次请求资源时,服务器会在响应头中添加一个Cache-Control或者Expires字段来指示浏览器资源缓存到本地,当下一次请求资源时,浏览器直接从本地缓存中获取资源,不再向服务器发起请求。 过期时间是固定的, Cache-Control中的值为:
- max-age 缓存最大过期时间
- no-cache 不使用本地缓存, 每次请求,服务器会取根据(last-modified | ETag资源唯一标识)==>判断是否需要重新传输该资源 如果资源未变化--> 服务器 --304 浏览器使用本地缓存
- no-store 禁止使用本地缓存 直接取服务器获取data
- 不存在该缓存结果和标识,强缓存失效,则直接向服务器发起请求
- 存在该缓存结果和标识,但结果已失效,强缓存失效,-->使用协商缓存
- 存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效直接返回结果
- 协商缓存 当强制缓存失效的时候,浏览器会向服务器发起请求,服务器在响应头中添加ETag或LastModifed字段来表示最后修改时间,下次请求该资源时,浏览器会在请求中添加if-None-Match字段来将标识符或者最后修改时间发送给服务器. 服务器根据这些信息来判断是否需要返回新的资源.如果资源没有发生更新,则服务器会返回304,浏览器从本地存储中获取资源,否则会返回新的资源。 协商缓存过期时间是不固定的,而是根据资源的标识符或最后修改时间来判断的。
协商缓存主要有以下 协商缓存上生效返回304 协商缓存失效,返回200和请求结果
8. == 和 === 区别
- == 和 === 区别 == 表示相等(值相等) === 表示恒类 (类型和值都要相等) == 则会先进行类型转换, 再判断值的大小,如果是 === 类型和值必须都相等.
- == === 和Object.is() 区别
- == 表示相等,如果两边类型不一致,进行隐式转换,再比较, +0和-0相等, NaN 不等于任何数
- === 严格相等, 如果类型不一致,就不相等。 +0和-0相等, NaN 不等于任何数
- Object.is() 严格相等,+0和-0不相等,NaN等于自身
9. script标签放在header里和放在body底部里有什么区别
- 放在header中 你能看到html第一时间被加载进来,但页面body内容迟迟没有渲染出来。因为在等待header标签中script脚本的加载,3s后,整个页面渲染完成.
- 放在body底部 这次html内容第一时间渲染完成,随后等待js的加载 总结 脚本会阻塞页面的渲染,所以推荐将其放在 body 底部,因为当解析到script标签时,通常页面的大部分内容都已经渲染完成,让用户马上能看到一个非空白页面。 另外你能看到多个脚本之间都是异步向服务器请求,他们之间不互相依赖,最终只等待3秒,而非3+3+3秒
速记二
10. Http1 Http2 Http3的区别
超文本传输协议 Http1.0 每次请求都需要重新建立TCP连接,请求完后立即断开与服务器的连接,造成了性能上了缺陷
- 问题 没有长连接 Http1.1
- 引入长连接(kepp-alive),较于http1.0 减少了连接和关闭的延迟,提高了效率,
- 支持管道传输 (同一个tcp连接上发送多个请求)
- 问题:-->
- 队头阻塞 还是未解决 若干个请求还是需要串行排队处理,如果有一个请求超时,后面的则就会阻塞(线头阻塞)
- 头部冗余且未压缩,在传输路线上造成了比较大的性能损耗
- 只能客户端发起
Http2.0 基于Https, 安全性肯定是没有问题的 性能改进
- 头部压缩 采用HPACK算法
- 静态字典(已有的、标准、常用的、高频的头部 出一套静态表)
- 客户端和服务端共同去维护一套字典
- 1 ---authority
- 2 --- method /GET
- 3 --- method /POST ....
- 8 --- 状态码 200
- 61 --- www-authenticate
- 动态字典
- 从62开始 不在静态表范围内的 用动态表构建
- 霍夫曼编码
- 静态字典(已有的、标准、常用的、高频的头部 出一套静态表)
- 头部压缩 采用HPACK算法
- 二进制帧
- 将文本格式 改为 ==> 二进制帧的格式
- 帧的好处 在于使用位运算进行高效解析
- 并发传输
- 多个stream(流)复用一条TCP连接,达到了一个并发的效果
- 不同的stream顺序可以不一致,在到达时,进行组装
- 服务端主动推送资源
- http1.1不支持主动推送 ,要实现的化,使用websocket协议
- C --S 基数 stream
- S --C 偶数 stream
HTTP2 问题
- tcp 协议 队头阻塞
- TCP TLS握手延迟
- 网络迁移需要重新连接
HTPP3
- 使用 QUIC+UDP 取代了 TCP协议 1. 更快的连接建立 2. 没有对头阻塞
- 头部压缩 由HPACK升级为==>QPACK
UDP 简单不可靠协议 UDP的包 中间是无序的
新的二进制格式传输,实现更加健壮,1.x版本是基于文本,解析存在缺陷 一个连接可以有多个请求,可以混杂在一起根据requestId区分不同的请求 提高了连接的利用率,降低了延迟 header头部压缩 通讯两方各自缓存了一份header请求头表,避免重复header的传输,且缩小了包的体积大小 服务端推送功能:可以服务端主动向客户端push消息 Http3.0
http的风险
全称(超文本传输协议) 是明文传输,存在 窃听(账号被人盗了)、篡改(页面被修改 眼睛看到的被垃圾污染了)、冒充(钱没了)
https 是如何解决的?
- CA证书 ---> 解决保证你访问的淘宝是真实的 (冒充风险)
- 信息加密 --> 解决被窃听
- 校验机制 --> 解决 篡改问题
信息加密
混合加密
- 对称 加密只有1个密钥,速度快, 但不安全
- 非对称 公+私 公钥任意分发,私钥保管 速度慢
例如 加盐 例如+10 hello qouuz 解密-10 -> hello
11. async await
async函数返回一个Promise对象,
js
function f(){return Promise.resolve('test')};
await 等价于 Promise.then() 返回的是Promise对象的结果 若不是Promise对象,则直接返回对应的值
js
async fucntion f(){}
f().then(v=>console.log(v)); // 123
不管await后面跟的什么,都会阻塞后面的代码
js
async fucntion fn1(){
console.log(1)await fn2();
// await阻塞下面代码(将其加入微任务队列) 先执行async外的同步,同步-> 再回到async函数中,再执行之前阻塞的代码
console.log(2);// 阻塞
}async function fn2(){
console.log('fn2');
}
fn1();
console.log(3); // 1 fn2 3 2
12.CSS新特性
- 过渡
js
transition:all .4s;
- 动画
js
// transform 适用于2D或3D转换的元素
transform:translate(30px,30px);
- 选择器 nth-of-type()
- 阴影 box-shadow: 10px 10px 5px #999
- 边框 border-image:url(border.png);
- 背景
- 文字
- 渐变
- Filter
filter: grayscale(100%)
- 弹性布局、格栅布局、多列布局
- 媒体查询
13. 加密算法
- 对称 加密只有1个密钥,速度快, 但不安全
- 非对称 公+私 公钥任意分发,私钥保管 速度慢
14. JS中的8种数据类型及区别
Number、String、Boolean、undefined、null、object、Symbol
15. position属性的值有哪些及其区别
js
// sticky(粘性定位) 表示元素再滚动到特定位置时将变为固定定位,
// fixed 相对于浏览器窗口定位
// absolute 相对于第一个父级不为static的元素定位
// relative 不改变文档流 直接基于原有位置定位
// sticky fixed和relative切换
// static normal
display属性 用于指定HTML元素的显式方式 控制元素在文档流中的位置和大小
- block 将元素呈现为块级元素 独占一行
- inline 行内元素, 与其他元素在同一行上
- inline-block 将元素呈现为行内块元素
- none 元素不显示,但仍然占据空间
- static 默认值
16. get post区别
1.针对数据操作的类型不同.GET对数据进行查询,POST主要对数据进行增删改!简单说,GET是只读,POST是写。
2.参数大小不同. GET请求在URL中传送的参数是有长度的限制,而POST没有限制
3.安全性不同. GET参数通过URL传递,会暴露,不安全;POST放在Request Body中,相对更安全
4.浏览器回退表现不同 GET在浏览器回退时是无害的,而POST会再次提交请求
5.浏览器对请求地址的处理不同 GET请求地址会被浏览器主动缓存,而POST不会,除非手动设置
6.浏览器对响应的处理不同GET请求参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留
17. var const let的区别
var 声明变量作用域为函数作用域或全局作用域 let const 则为块级作用域 var存在变量声明提升 let const不存在变量声明 使用var声明的变量都可以被重复声明 后面的声明覆盖前面的声明 let const 在同一作用域中不允许被重复声明 否则报错
const 声明变量必须进行初始化赋值,不能再次赋值,但let var 则可以 cosnt声明为常量 let var则为变量 可以修改 let const存在暂时性死区 (Temporal Dead Zone ) 例如用let 声明一个变量 那么在该变量声明之前,使用该变量都会抛出错误 TDZ
18. CSS盒子模型
css中的盒子模型分为IE盒子模型(怪异盒模型)和标准盒子模型 标准盒子的宽度为 width + margin + padding +border 怪异盒子 width(padding+border) +margin box-sizing: border-box(怪异) | content-box (标准)
19. WebSocket
实现客户端与服务端的双向通信,只需一次连接,就可以互相传输数据
- 应用场景为: 实时通讯、数据实时更新
- 优点: 双向通信,客户端和服务端双方都可以主动发起通讯,没有同源限制,客户端可与任意服务器通信,不存在跨域通信
- 缺点: 长连接需要后端处理业务的代码更稳定,推送消息更加复杂 受到网络限制大,兼容性> IE10+ 维护成本高
速记三
20. BFC 块级格式上下文
一个独立的渲染区域,区域内的元素不会影响到外面的元素,
创建BFC
- float不为none
- position 为 absolute|fixed
- dispaly 为 inline-block | table-cell table-caption | inline-flex/grid /inline-grid
- overflow为非 visible的值 (auto 、scroll、hidden)
BFC使用场景
- 去除边距重叠现象
- 清除浮动
- 避免某元素被浮动元素覆盖
- 避免多列布局因为宽度计算四舍五入而自动换行
BFC的原理布局规则
- 内部的Box独占宽度,且在垂直方向上,轮流排列
- Box垂直方向的距离由margin决定
- 同一个BFC的两个相邻的box的margin会发生折叠现象
- 每个box水平方向上左边缘,与BFC的左边缘对齐,即使浮动也是如此
- 元素的类型和display属性,决定Box的类型
- BFC的独立容器,不影响外面的元素
- 计算BFC的高度时,浮动元素也参与计算高度
如果让一左边固定宽度 右边自适应 可以给右边.right独立的BFC overflow:hidden即可 或者左边固定宽度 右边flex:1
- 同一个div内的两个元素 出现margin重叠 则只需要给其他一个设置BFC即可
js
<h3>bfc 例3</h3>
<div>
<p>posotmk1</p>
<div class="wrap">
<p>posotmk2</p>
</div>
</div>
bfc是一层一层的东西 ,ffc(弹性盒子格式上下文)关注的是 这一层声明了flex,下一层中的直接的容器有什么样子的关系 bfc则是我要不要参与上下文布局
- 两栏布局
html
<!-- 浮动 -->
<style>
.bot{
overflow: hidden;// 添加BFC
}
.left{
float: left;
width:200px;
background-color:red;
height:200px;
}
.right{
height: 200px;
margin-left: 210px;
background-color: yellow;
}
</style>
<div class="bot">
<div class="left"></div>
<div class="right"></div>
</div>
<!-- 2. flex -->
<style>
.bot{
display:flex;
}
.left{
width:200px;
background-color:red;
height:200px;
}
.right{
flex:1;
background-color:blue;
}
</style>
- 三栏布局 中间布局
html
<style>
.bot{
display: flex;
justify-content: space-between;
}
.left,.right,.middle{
height: 100vh;
}
.left{
width: 200px;
background-color: red;
}
.right{
width: 120px;
background-color: blue;
}
.middle{
flex: 1;
background-color: aqua;
}
</style>
<div class="bot">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
<!-- 第二种float -->
<style>
.wrap {
background: #eee;
overflow: hidden;
/* 生成BFC,计算高度时考虑浮动的元素 */
padding: 20px;
height: 200px;
}
.left {
width: 200px;
height: 200px;
float: left;
background: coral;
}
.right {
width: 120px;
height: 200px;
float: right;
background: lightblue;
}
.middle {
margin-left: 220px;
height: 200px;
background: lightpink;
margin-right: 140px;
}
</style>
<div class="wrap">
<div class="left">左侧</div>
<div class="right">右侧</div>
<div class="middle">中间</div>
</div>
21. Socket连接的步骤
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
1、服务器监听:处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
客户端的套接字:指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3、连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。
而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
22. 数据类型的判断 instanceof 和typeof 的区别
- tyepof 只能判断基本类型和函数类型 但是数组和对象无法判断 返回结果为字符串
- instanceof 能够区分Object Function Array 能够判断类实例对象 无法判断基础数据类型number、string、boolean
- Object.prototype.toString.call() 可以精准判断数据类型
23. 隐藏页面元素的方法
- opacity: 0,更改透明度,使得元素隐藏起来,但不会改变页面布局(重绘), 如果该元素已经绑定了一些事件,如click事件,那么点击该区域,也能触发点击事件
- visibility:hidden, 设置元素是否可见, 在文档流布局中仍然保留原来的空间(重绘),但是不会触发该元素绑定的事件,
- display:none, 把元素隐藏起来,改变页面布局, 不显示对应的元素,在文档流布局中不再分配空间(回流+重绘)
- CSS的方法 postion:absolute, left:-9999px; transform:scale(0)
24. DNS协议是什么
DNS服务器通过多层查询将解析域名为IP地址 域名劫持: 指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或什么都不做使请求响应, 效果就是对特定的网络不能访问或访问的是假网址
25. 浅拷贝和深拷贝的区别
浅拷贝
如果是基本数据类型,则拷贝的是基本类型的值,如果是引用类型,则拷贝的就是内存地址, 浅拷贝是拷贝一层,深层次的引用类型则共享内存地址Object.assign 扩展运算符 Array.prototype.slice()
js
const obj = {};
const source = {
name:'nosd',
info:{
age:22
}
};
Object.assign(obj, source);// (目标对象,源对象)
const obj ={...source};
const arr = [1,2,{name:'tioan'}];
cont newsOd = arr.slice();
newsOd[2].name ='ss';
- 深拷贝 开辟一个新的栈,两个对象完全相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
- _.cloneDeep()
- JSON.stringify()
- 递归实现
js
fucntion deepCopy(target){
if(tpyeof === 'object'){
// 判断是否为Object 是的话,创建新的对象,用于存储拷贝的值 然后遍历属性 进行递归
const newTarget = Array.isArray(target)?[]:Object.create(null);
for(const key in target){
newTarget[key] = deepCopy(target[key]);
}
return newTarget;
}else{
return target;
}
}
26. flex布局
flex ---flexible box 弹性布局
容器属性
- flex-direction 主轴的方向
- row -- default 水平
- column 垂直
- flex-wrap 换行
- nowrap ---default
- wrap
- wrap-reverse 反转
- flex-flow 为flex-direction flex-wrap的合并
- 默认为row nowrap
- justify-content 主轴的对齐方式
- flex-start ---default 左对齐
- flex-end 右对齐
- center 居中
- space-between 两端对齐,项目之间的间隔都相等
- space-around 两侧间距相同
- space-evenly 每块间距相同
- align-items 交叉轴 垂直方向
- flex-start ------
- flex-end ------
- center ------
- baseline 项目的第一个行文字的基线对齐
- stretch 占满高度 拉伸
项目属性
- order
- 0 ----default 项目的排列顺序,数越小,排列越靠前
- flex-grow
- 0 ----default 放大比例 剩余空间
- flex-shrink
- 1 ----default 缩小比例,剩余空间
- flex-basis
- auto ----default 定义在分配多余空间前,项目占据的空间
- flex: 1
- 表示 flex: 1 1 0%
- flex: auto 1 1 auto
- flex: none 0 0 none
27. 浏览器的主要功能
浏览器的主要组成部分是什么?
- 用户界面
- 呈现引擎
- 网络
- 用户界面后端
- js解释器
- 数据存储
- 浏览器引擎
28. 闭包
一个普通函数,如果它可以访问外层作用域的自由变量,那么这个函数和周围的环境就是一个闭包; 广义:js中的函数都是闭包 狭义:js中的一个函数,如果访问了外层作用域的变量,那么它是一个闭包;
js
var name = 'tian';
var age = 20;
var address = 'xaau';
// foo函数外面的name,age address 这些都是自由变量
function foo(name,age,address,num1,num2){
var message = 'hello world';
console.log(name,age,address); // 函数内部使用外层作用域的自由变量 这就是-->形成了闭包
}
function bar(){
console.log(name);
}
bar();
foo(name,age,address,20,30);
缺点: 可能造成闭包泄露
闭包的两个场景,闭包的两大作用:保存/保护。 在开发中, 其实我们随处可见闭包的身影, 大部分前端JavaScript 代码都是“事件驱动”的,即一个事件绑定的回调方法; 发送ajax请求成功|失败的回调;setTimeout的延时回调;或者一个函数内部返回另一个匿名函数,这些都是闭包的应用。
29. rem布局
1rem = 10px
速记四
30. 浏览器如何渲染UI
浏览器渲染HTML文件,会文件进行解析,形成DOM Tree
首先从获取到服务器返回的index.html文件,进行HtmL解析,构建DOM Tree
在解析HTML的同时,遇到link标签,进行下载CSS的文件,进行解析,生成style Rules 然后DOM Treee + style rules ==> attachments render tree ==>layout 计算每个节点的几何体
render tree 会表示显示树中的所有节点以及样式 然后进行painting(绘制) 最后进行display 展示
DOM Tree 构建
js源码 -> parse(解析)--> 转化为AST --> ignition(解释器)--> bytecode字节码 ignition --> trubFan(编译器) -->j将bytecode翻译为CPU可以运行的MachineCode(机器码)
DOM Tree是如何构建的?
1、转码: 浏览器将接收到的二进制数据按照指定编码格式转化为HTML字符串
2、生成Tokens: 之后开始parser,浏览器会将HTML字符串解析成Tokens
3、构建Nodes: 对Node添加特定的属性,通过指针确定 Node 的父、子、兄弟关系和所属 treeScope
4、生成DOM Tree: 通过node包含的指针确定的关系构建出DOM
31. 浏览器重绘与回流
回流 reflow 第一次确定节点的大小和位置,称为布局之后对节点大小、位置的修改 什么情况下引起回流
- DOM结构
- 布局 width height border padding margin fontsize
- 视窗口大小
- 调用getcomputedStyle获取位置、尺寸信息
- 激活伪类
重绘 第一次渲染之内容称为绘制,之后的重新渲染都成为重绘(painting) 什么情况下引起重绘
- color visibility opcaity border-style
开发中尽量避免发生回流 避免频繁操作DOM 修改样式尽量一次性修改
32. 百分比布局
通过%来实现响应效果 缺点 ——————> 计算比较困难
33. 行内块元素 块级元素 空元素
- block h1~h6 address ul li ol table p hr div form 独占一行 可以设置宽高
- inline span a br b img input textarea select 不独占 不可以设置宽高
- inline-block img input textarea select button 不独占 可以设置
34. 浮动布局
浮动元素脱离文档流 就会无法撑起来父元素===> 父元素高度塌陷
例如浮动元素的父元素没有设置高度则父元素高度塌陷 可以通过
- 第一种 清除浮动
js
.clearfix::after{
content:'';
display:block;
clear:both;
}
- 创建BFC overflow:hidden
35. cookie localStorage sessionStorage区别
存储在客户端
- cookie 大小限制 <4k cookie的数据自动传递到服务器 不设置过期时间 存在内存中 | 设置了存在硬盘
- localStorage >5M 本地浏览器
- sessionStorage >5M 浏览器关闭之后则自动删除 存储字符串的数据
应用场景
- 标记用户与跟踪用户行为的情况 cookie
- 长期保存 -- localStorage
- 一次性 sessionStorage
36. 获取表单元素的事件
- document.getElementById
- getElementByTagName 标签名
- getElementByName
- getElementByClassName
- querySelector 选择器获取元素
37. em/px/rem/vh/vw 区别?
- rem 根据html的字体大小动态变化的单位
- em 相对父元素的字体单位大小
- vw 视窗宽度的1%
- vh 视窗高度的1%
- px(pixel)
38. WEB安全
- XSS攻击 恶意脚本插入 过滤用户输入内容
- 输入长度限制
- 输入格式过滤 校验
- 转义特殊
- CSRF(跨站请求伪造)
- 攻击者利用用户身份进行非法操作的网络攻击
- 受害者登录了社交网站,攻击者在另一个网站中插入了一个恶意的表单,当受害人提交表单时,攻击者就能够以受害者的名义发表有害信息
- 为了防止CSRF
- cookie标记
- 使用验证码
- 验证http请求资源
- SQL注入
- 攻击者通过在web应用程序中的表单或URL 参数中注入恶意的SQL代码,以获取未经过授权的访问和信息 | 攻击者通过web应用程序向后端数据库发起恶意的SQL查询
- 限制用户输入的长度和格式
- 定期更新web应用程序和数据库
- 参数化查询 将用户输入的信息作为参数进行查询而不是简单拼接到SQL语句
- 攻击者通过在web应用程序中的表单或URL 参数中注入恶意的SQL代码,以获取未经过授权的访问和信息 | 攻击者通过web应用程序向后端数据库发起恶意的SQL查询
速记五
39. 如何使用 rem 或 viewport 进行移动端适配
- rem适配原理
改变一个元素在不同设备上占据的像素个数 px --> rem 麻烦 - viewport适配原理 每一个元素在不同的设备上占据的css像素个数都是一致的 缺点-- 破坏完美视口
40. 输入 URL 回车后发生了什么?
输入URL后 检查缓存 -->解析出协议、主机、端口、路径 构造一个HTTP请求 DNS解析 TCP连接 三次握手 发送HTTP请求 服务器处理请求返回HTTP报文
浏览器解析渲染页面 断开连接
HTML解析构建DOM 转码 将收到的数据进行格式转化为HTML字符串 生成TOKEN 开始进行解析,浏览器将HTML字符串解析成TOKENs 构建NODEs 对Node添加属性 确定NOde的父、子 兄弟 关系和所属treeScope 生成DOM tree 通过node包含的指针确定的关系构建DOM
- DNS解析 找到对应的IP地址
- TCP连接
为什么需要三次握手,两次不行吗?其实这是由 TCP 的自身特点可靠传输决定的。 客户端和服务端要进行可靠传输,那么就需要确认双方的接收和发送能力。第一次握手可以确认客服端的发送能力,第二次握手,确认了服务端的发送能力和接收能力,所以第三次握手才可以确认客户端的接收能力。不然容易出现丢包的现象 - 发送HTTP请求--http报文包裹在TCP报文中请求行、请求头、请求正文
- 服务器处理请求返回http报文 ---状态码 响应报文 正文
- 浏览器解析渲染界面 浏览器在收到html css js后依次渲染
- 连接结束 断开TCP连接 四次握手
二次握手
- 客户端发送连接,因为连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求,后来收到确认了,建立了连接,数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段。其中第一个丢失,第二个到达了服务器,但是第一个丢失的报文段只是在某些网络节点时间滞留了,延误了
流程
- URL输入
- 检测 输入的内容是否是一个合法的URL连接
- 判断输入的URL是否完整,若不完整,则浏览器可能会对域名进行猜测补全前缀或后缀
- 使用用户默认的搜索引擎来进行搜索
- DNS解析
- 浏览器不能直接通过域名找到对应的服务器IP地址,所以需要进行DNS解析,查找对应的IP地址进行访问
- 建立TCP连接
- 发送Http/Https请求
- 向服务器发送TCP请求
- 这个请求到达服务器后,通过TCP三次握手,建立TCP的连接
- 客户端发送SYN包到服务端后,并进入SYN_END状态,等待服务器的确认
- 服务器收到SYN包,必须确认客户的SYN,同时自己也发送SYN包,此时,服务器进入SYN_RECY状态
- 客户端收到服务器的SYN包,向服务器发送确认包,此包发送完毕,客户端和服务器进入established状态完成三次握手,
- 服务器响应请求
- 浏览器到web服务器的连接建立后,浏览器会发送一个初始化的HTTP get请求,请求的目标通常是一个HTML文件,服务器收到请求后,将发回一个HTTP响应报文,内容包括相关响应头和HTML正文
- 浏览器解析渲染页面
- 处理HTML标记并构建DOM树
- 处理CSS标记并构建CSSDOM树
- 将DOM与CSSDOM合并成为一个渲染树
- 根据渲染树来布局,以计算每个节点的几何信息
- 将各个节点绘制到屏幕上
- HTTP请求结束,断开TCP连接
41. html dom的event事件
- onblur
- onfocus
- 加载事件 - onload 图完成加载
- 鼠标事件
- onmousedown 按下
- onmouseup 松开
- onmousemove 移动
- onmouseout 移走
- onmouseover 鼠标移动到某元素之上
- 键盘事件
- onkeydown 按下
- onkeypress 按下并松开
- onkeyup 松开
- 选择和改变
- onchange
- onselect
- 表单事件
- onsubmit
- onreset 重置
42. 清除浮动的方式
- 父元素末尾添加空元素并设置清除浮动
<div style='clear:both'></div>
- 好处:通俗易懂
- 缺点: 不利于后期维护
- 给父元素添加overflow:auto
- 让父元素浮动
- 影响布局
- 伪元素
- 父元素添加一个类 添加看不见的块,以清除浮动
- BFC 防止高度塌陷
43. AJAX原理
异步的js和xml在无刷新情况下与服务器进行通信,来更新部分用户界面 通过XMLHttpRequest对象来向服务器发异步请求--> 获取data --js操作DOM更新页面
js
//1.创建对象
const btn = document.querySelector('button');
btn.onclick = function () {
//1.创建对象
const x = new XMLHttpRequest();
// 2.初始化设置
x.open('GET', "http://127.0.0.1:9000/cors-server");
// 3.发送
x.send();
// 4.绑定事件
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 & x.status < 300) {
//输出响应体
console.log(x.response);
}
}
}
}
CORS设置跨域
js
const express = require('express');
const app = express();
//Cors请求服务
app.all('/cors-server', (request, response) => {
//这里我们需要注意 设置响应头
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
response.setHeader('Access-Control-Allow-Method', '*');
response.send('cors-server');
})
app.listen(9000, () => {
console.log('服务已经启动...');
})
44. css 预处理器 sass less stylus的区别
什么是CSS预处理器?
CSS预处理器是一种语言用来为CSS增加一些变成的特性,无需考虑浏览器兼容问题,例如你可以在CSS中使用变量,简单的程序逻辑、函数等在编程语言中的一些基本技巧,可以让CSS更加简洁,适应性更强,代码更直观等诸多好处
基本语法区别
Sass是以.sass为扩展名,Less是以.less为扩展名,Stylus是以.styl为扩展名
变量的区别
Sass 变量必须是以$开头的,然后变量和值之间使用冒号(:)隔开,和css属性是一样的。 Less 变量是以@开头的,其余sass都是一样的。 Stylus 对变量是没有任何设定的,可以是以$开头或者任意字符,而且变量之间可以冒号,空格隔开,但是在stylus中不能用@开头
45. 前端性能优化
- 减少http请求 合并图片,当图片较多时,可合并为一张大图,从而减少http请求数 合并压缩js|css
- 图片优化 尽可能使用PN格式图片,相对而言体积小,但是现在svg是不错的选择
- 使用CDN CDN即内容发布网络,可以使用户就近取得所需内容,解决网络拥挤的情况,提高用户访问网站的响应速度。
- 开启GZIP
- nginx中内置了ngx_http_gzip_module模块 做Gzip的文件压缩 它基于 Deflate 算法,可将文件压缩地更小,从而实现更快的网络传输。
md
# 开启压缩功能,on 表示开启 off 表示关闭,默认是 off
gzip on;
#表示允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,表示不管页面多大都进行压缩,建议设置成大于1K。如果小于1K可能会越压越大。即:小于设置值的文件将不会压缩
gzip_min_length 1k;
# 设置压缩所需要的缓冲区大小
gzip_buffers 4 32k;
# 设置gzip压缩针对的HTTP协议版本
gzip_http_version 1.1;
# gzip 压缩级别,1-9,数字越大压缩的越好(一般选择4-6),也越占用CPU时间
gzip_comp_level 6;
gzip_types text/css text/xml application/javascript;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
- 构建优化
按需加载 将不同的模块分割成为小块
webackbundle
使用Tree-shaking 清除构建过程中无用的代码,可以减少构建后文件的体积
46. call apply bind 的区别
- call apply bind的相同点
- 都可以改变this指向,
- 第一个参数为this指向的对象,
- 都可以利用后续参数传参
- 区别
- call bind 依次传参 一一对应的
- apply 则只有2个参数 第二个参数为数组
- call apply 都是对函数进行直接调用,bind方法返回的仍然是一个函数
47. 元素水平垂直居中
仅居中元素定宽高适用
- absolute + 负margin
- absolute + margin auto
- absolute + calc
居中不定高度
- lineheight
- pa
- table
- css-table
- flex
- grid
- PC端有兼容性要求,宽高固定,推荐absolute+负margin
- PC端无兼容性要求,推荐flex
- PC端有兼容要求,宽高不固定,推荐css-table
速记六
48. 如何理解CDN 实现原理
内容分发网络: 构建在现有网络基础上的智能虚拟网络 使用户就近获取所需内容,降低网络拥塞 提高用户访问响应速度和命中率
CDN的关键技术 主要为内容存储和分发技术 简单来说,CDN就是根据用户位置分配最近的资源 应用CDN后,DNS返回的不再是IP地址,而是一个个CHAME(别名记录),指向了CDN的全局负载均衡。
CHAME实际上在域名解析的过程中承担了中间人的角色,这是CDN实现的关键。
49. 伪元素、伪类区别
伪类 点击操作 是一个以冒号作为前缀, 被添加到一个选择器末尾的关键字,当你希望样式在特定状态下被呈现到指定的元素时,你可以往元素的选择器后面加上对应的伪类。 伪元素 --after、before用于创建一些不在文档树中的元素,并为其添加样式,比如说,我们可以通过::before来在一个元素前添加一些文本, 并为其文本添加样式 。 虽然用户可以看到这些文本,但是这些文本实际不在文档树中。
区别
伪类是通过元素在选择器上加入了伪类改变了元素的状态
伪元素是通过对元素的操作进行对元素的改变
50. 跨域
跨域一般至的是浏览器端跨域,因为服务器端是没有跨域, 浏览器因为同源策略(协议、域名、端口号) 若有一个不同则会导致跨域
解决方法:
- jsonp get请求不安全 携带数据小,
- cors 设置响应头
js
const express = require('express');
const app = express();
//Cors请求服务
app.all('/cors-server', (request, response) => {
//这里我们需要注意 设置响应头
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*'); // 允许访问的域
response.setHeader('Access-Control-Allow-Headers', '*'); // 设置允许的请求头
response.setHeader('Access-Control-Allow-Method', '*');// 设置允许的请求方法
})
app.listen(9000, () => {
console.log('服务已经启动...');
})
- vue中
js
// vue.config.js
module.exports ={
devServer:{
host: 'localhost',
port: 3000,
open: true,// vue自动打开浏览器
proxy:{
'/api':{ // /api代理标识, 告诉node url前面的/api就是使用代理的
target:'http://xx.comx.xx:8000',// 目标地址
changeOrigin:true,
pathRewrite:{ // 将实际请求的url中的/api用""代替
"^/api":""
}
}
}
}
}
- React中 创建setupProxy
js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'https://bang.360.cn',
changeOrigin: true,
pathRewrite: {
"^/api": ""
}
})
);
};
51. Event Loop 执行顺序
同步任务: 按照代码顺序依次来执行的任务,每个任务必须等前一个任务完成后才能执行
异步任务: 不按照顺序依次执行的任务,是在某些事件触发或某些条件满足时才执行的任务。 异步任务不会阻塞后续的代码执行,因为通常在后台执行。 常见的异步任务包括定时器、网络请求等
宏任务: 由浏览器发起的任务,它们通常需要较长时间才能完成,包括 DOM操作、setTimeOut setInterval setImmediate I/O UI交互事件 postMessage script(整体代码)
微任务: 由js自身发起的任务, 通常需要较短时间就可以完成,包括Promsie 、MutationObserver、 process.nextTick 优先级 > promise 、 async/await
执行顺序
代码从开始执行调用一个全局执行栈,script标签作为宏任务执行
执行过程中同步代码立即执行,异步代码放到任务队列中,任务队列存放有两种类型的异步任务,宏任务队列,微任务队列。
同步代码执行完毕也就意味着第一个宏任务执行完毕(script)
1、先查看任务队列中的微任务队列是否存在宏任务执行过程中所产生的微任务 - 1-1、有的话就将微任务队列中的所有微任务清空 - 2-2、微任务执行过程中所产生的微任务放到微任务队列中,在此次执行中一并清空
2、如果没有再看看宏任务队列中有没有宏任务,有的话执行,没有的话事件轮询第一波结束 - 2-1、执行过程中所产生的微任务放到微任务队列 - 2-2、完成宏任务之后执行清空微任务队列的代码
js
同步的代码
|
process.nextTick / promise...
|
┌───────────────────────────┐
┌─>│ timers │ 定时器: setTimeout / setInterval
│ └─────────────┬─────────────┘
| process.nextTick / promise...
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │ 执行延迟到下一个循环迭代的I/O回调
│ └─────────────┬─────────────┘
| process.nextTick / promise...
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │ 系统内部使用
│ └─────────────┬─────────────┘ ┌───────────────┐
| process.nextTick / promise...
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
| process.nextTick / promise...
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │ setImmediate
│ └─────────────┬─────────────┘
| process.nextTick / promise...
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │ 关闭回调函数
└───────────────────────────┘
js
console.log('1');
setTimeout(function () {
console.log('2');
process.nextTick(function () {
console.log('3');
})
new Promise(function (resolve) {
console.log('4');
resolve();
}).then(function () {
console.log('5')
})
})
process.nextTick(function () {
console.log('6');
})
new Promise(function (resolve) {
// new Promise(function (resolve) { 是构造函数 同步执行的
console.log('7');
resolve();
}).then(function () {
console.log('8')
})
setTimeout(function () {
console.log('9');
process.nextTick(function () {
console.log('10');
})
new Promise(function (resolve) {
console.log('11');
resolve();
}).then(function () {
console.log('12')
})
})
// 1 7 6 8 2 4 3 5 9 11 10 12
/**
* 思路分析
* 同步任务 1,将setTimeOut放入到宏任务队列中等等
* 遇到process.nextTick,其回调函数被分发到微任务队列中
* 遇到new Promise构造函数,是一个同步操作 输出 7,并将.then分发到微任务队列中等待
* 然后又遇到setTimeout ,回调函数被分发到宏任务队列中,
* 然后第一轮的宏任务直接完了,输出 1 7 接着清空 微任务队列 6 8
* 第二轮从setTimeout开始,输出 2
* 遇到process.nextTick 分发到微任务队列中
* new Promsie 同上 然后输出4 并将.then分发到微任务队列中等待
* 然后遇到setTimeout 被分发到宏任务队列中
* 此时 第二轮结束了,接着清空微任务队列 输出 3 5
* 第三轮从 setTimeout开始, 输出 9
* 遇到nextTick放入微任务队列
* new Promise 同步操作 输出 11 遇到.then 分发到微任务队列中等待
* 第三轮宏任务队列结束,清空微任务队列 输出 10 12
*/
js
async function async1() {
console.log('async1 started'); // 2
await async2();
console.log('async end'); // 12
}
async function async2() {
console.log(`async2`); //3
}
console.log('script start'); // 1
setTimeout(() => {
console.log('setTimeout0'); // 0
setTimeout(() => {
console.log('setTimeout1'); // 11
}, 0);
setImmediate(() => {
console.log('setImmediate'); // 10
})
}, 0);
async1();
process.nextTick(() => {
console.log('nextTick'); // 7
});
new Promise((reslove) => {
console.log('promise1'); // 4
reslove();
console.log('promise2'); // 5
}).then(() => {
console.log('promise then'); //8
});
console.log('script end'); // 6
52. 渐进增强与优雅降级的理解及区别
- 渐进增强(Progressive Enhancement):
一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。
- 优雅降级(Graceful Degradation):
一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。
两者区别 1、广义: 其实要定义一个基准线,在此之上的增强叫做渐进增强,在此之下的兼容叫优雅降级 2、狭义: 渐进增强一般说的是使用 CSS3 技术,在不影响老浏览器的正常显示与使用情形下来增强体验,而优雅降级则是体现 html 标签的语义,以便在 js/css 的加载失败/被禁用时,也不影响用户的相应功能。
53. 浏览器样式兼容
- CSS初始化
每个浏览器的css默认样式不同,最简单的方法就是对其进行初始化(覆盖默认样式)
常见 *{margin:0;padding:0} 库 normalize.css
- 浏览器私有属性
常用的前缀有: firefox: -moz- | chrome、safari:-webkit-| IE -ms-
- CSS hack (条件hack、 属性级hack、选择符级hack)
54. 列举ES6新特性
- let const
- promise
- class
- map set
- map
- set(key, value)向字典中添加新元素。
- get(key) 通过键查找特定的数值并返回。
- has(key) 判断字典中是否存在键key。
- delete(key) 通过键 key 从字典中移除对应的数据
- clear() 将这个字典中的所有元素删除
- 遍历方法 keys() values() entries() foEach()
- set
- add(value)新增,相当于 array里的push
- has(value)判断集合中是否存在 value。
- delete(value) 存在即删除集合中value。
- clear() 清空集合
- map
- 箭头函数
- 函数参数默认值
- 模板字符串
- 解构赋值
- 展开运算符
- 构造
- symbol
- 模块化
js
// 1.默认导出
export default function test(){
console.log('hello world');
}
import test from '...xx.js'
// 2. 命名导出
export const name = 'djsd';
export{name,age};
import {name,age} from './xx.js'
// 3. 整体导出
export * from './xx.js';
// 导入
import * as myModule from './xx.js'
55. 常见的兼容性问题
不同浏览器的标签默认的margin和padding不一样。
*{margin:0;padding:0;}
IE6 双边距 bug:块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大。hack:display:inline; 将其转化为行内属性。
设置较小高度标签(一般小于 10 px),在 IE6,IE7 中高度超出自己设置高度。hack:给超出高度的标签设置overflow:hidden; 或者设置行高 line-height 小于你设置的高度。
Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示,可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决。
超链接访问过后 hover 样式就不出现了,被点击访问过的超链接样式不再具有 hover 和 active 了。解决方法是改变 CSS 属性的排列顺序 :L-V-H-A ( love hate ): a:link {} a:visited {} a:hover {} a:active {}
56. GC回收机制
主要是 页面中存在大量不被释放的内存,页面性能会变得很慢。造成内存泄露。尽可能的减少闭包。因为它会消耗内存。 常见内存泄露 全局变量、闭包、DOM元素的引用、定时器
标记清除: 变量进入执行环境时,被标记为'进入环境',当变量离开执行环境时,浏览器会回收它,如果被占用,就不能回收。
谷歌浏览器是: 查找引用, 浏览器不定时去查找当前的内存的引用,如果没有被占用则回收,
57. 什么是作用域 ? 什么是作用域链 ?
创建函数的时候,已经声明了当前函数的作用域==>当前创建函数所在的上下文
- 定义: 变量和函数的可访问范围,由当前环境和上层环境的一系列变量对象组成
- 全局作用域: 代码在程序的任何地方都可以被访问,window对象的内置属性都由全局作用域
- 函数作用域: 只有在固定片段才可访问
作用: 隔离变量,不同作用域下同名变量不会有冲突 作用域链: 一般情况下,变量到创建该变量的函数的作用域中取值。 若当前作用域中没有则去上层作用域中查找
58. webpack中loader和plugin的区别
- loader
- 在打包前或打包期间调用
- 根据不同的匹配条件处理资源
- 调用顺序与书写顺序相反
- 写在前面的接收写在后面的返回值作为输入值
- plugin
- 基于 Tapable 实现
- 事件触发调用,监听 webpack 广播的事件
- 不同生命周期改变输出结果
59. 让一个元素水平垂直居中的方法
- 绝对定位方法 不确定宽高时
css
div{
position: absolute;
left:50%;
top:50%;
transform:translate(-50%, -50%);
}
- 确定当前div的宽高
css
.osp{
width: 200px;
height: 200px;
margin: -100px auto;
border: 2px solid red;
}
- 绝对定位上下左右为0
css
div{
width: 200px;
height: 200px;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
border: 2px solid red;
}
- flex布局 给父级添加flex样式
js
.osp{
display: flex;
align-items: center;
justify-content: center;
}
.dd{
width: 200px;
height: 200px;
border: 2px solid red;
}
- table-cell 实现水平垂直居中 table-cell middle center 组合使用
css
display:table-cell;
vertical-align:middle;
text-align:center;
- 绝对定位: calc计算
60. 自定义webpack插件
- 声明一个自定义命名的类或函数
- 在原型中新增apply方法
- 声明由Compiler模块暴露的生命周期函数
- 使用webpack提供的API或自行处理内部实例的数据
- 处理完后,调用webpack提供的回调函数
61. import import() require区别
62. async/await 的错误捕获方式
- try catch
js
async function a(){
try{
await doSth1()
}catch(e){
throw e
}
}
- Promise的catch方法
js
async function a(){
await doSth1()
}
a().then().catch()
//或者
a().then(()=>{
//成功
},()=>{
//失败
})
63. box-sizing 所有的属性
content-box: 标准盒子模型 border-box 怪异 inherit 继承父元素的box-sizing
64. get post的区别
get 发送一个请求来取得服务器上的某一个资源 检索->获取
post 向url指定的资源提交数据或附加新的数据 创建->更新
post用于修改和写入数据, get一般用于搜索或筛选之类的操作(淘宝、支付宝的搜索查询都是get提交)目的是资源的获取、读取数据
- 参数位置不同
post中
js
export const dsd = (params) => request.post('/article/add',params);
export const ArticleApi = (params)=> request.get(`/article/${params.id}`)
65. hash history区别
hash兼容性好, 地址中带# 不会重新加载页面 hash值不会带给服务器 出现在url中
路由器 | hash模式 | history模式 |
---|---|---|
兼容性 | 较好 | 较差 |
URL | 出现url中,不在http中 | 与http保持一致以/开头 |
服务器 | hash值不会带给服务器 | 部署上线需后端解决刷新404问题 |
美观性 | 带#号 | 美观 |
加载页面 | 不会重新加载 | 会重新加载 |
66. 进程和线程、 协程
进程 并发执行的程序在执行过程中分配和管理资源的单位,
线程 进程的一个执行单元,
协程 比线程更加轻量级的存在
67. 图片懒加载
vue中
js
给需要懒加载的图片设置缩略图或自定义属性 data-src 判断图片是否在可视区域内,若在,则将src属性值更换为真正的地址 用户滚动窗口区域时,遍历所有需要懒加载的元素,通过每个元素的getBoundingClientRect
属性来判断元素是否在可视区域内,
js
function isInViewPort(element) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
window.addEventListener("scroll", () => {
const images = document.querySelectorAll("img[data-src]");
for (const image of images) {
if (isInViewPort(image)) {
image.setAttribute("src", image.getAttribute("data-src"));
image.removeAttribute("data-src");
}
}
});
// 当前元素相对于视窗口的信息
68. 文档流
- 什么是文档流?
网页在解析时,遵循从上到下、从左到右的顺序
- 如何脱离文档流?
- float
- position absolute
- fixed
- 脱离文档流会造成什么问题?
- 脱离文档流是指,标签脱离了文档流的管理,不受文档流的布局约束了,该标签在原文档流中所占的空间也被清除了
- 脱离文档流的元素处在浮动状态(可以理解为漂浮在文档流的上方)
69. 异步编程的发展历程
一个任务分成两段,先执行一段,转而执行其他任务,等做好了这边 回调函数--> Promise --> Generator --> async,await
- 回调函数(callback)
js
function A(callback){
callback();
console.log('我是主函数');
}
- Promise
处理异步操作,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作
js
new Promise(
function (reslove,reject){
if(/**success */) {
resolve();
}esle{
/**fail */
reject();
}
}
)
Promise.prototype.then 实例化后的Promise对象可以进行链式调用
Promise.prototype.catch 捕获异步操作时出现的异常
Promise.all() 将数组中所有的任务执行完成后,才执行.then中的任务,全部为fulfilled时,它才会变成fulfilled,否则变成rejected
Promise.race() 一旦参数内有一个值的状态发生的改变,那么该Promised的状态就是改变的状态
Promise.resolve() 接受一个参数值,可以是普通的值,具有的then()的方法的对象和Promise实例
Promise.reject() 它接受一个参数reason,即发生异常的原因
- 优点 可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
- 缺点 无法取消Promise 错误需要通过回调函数来捕获 当处于pending的状态时,无法得知目前进展到哪一个阶段
- Generator
- 在function关键字后加了一个*,那么这个函数就称为generator函数
- 函数体有关键yield, 后面跟每一个任务,也可以有return关键字,保留一个数据
- 通过next函数调用,几个调用,就是几个人在任务执行
单行& 多行溢出
js
overflow:hidden;
-webkit-line-clamp:3;
-webkit-box-orient:vertical;
display:-webkit-box;
单行文字溢出
js
text-overflow:ellipsis;
overflow:hidden;
white-space:nowrap;