来吧
浏览器请求
浏览器输入URL发生什么?
- 第一步:url地址解析
- 第二步:缓存检查
- 第三步:DNS解析
- 第四步:三次握手
- 第五步:基于Http的数据传输
- 第六步:四次挥手
- 第七步:浏览器渲染
性能优化有哪些?
- GZIP压缩
- 静态页面做强缓存或协商缓存
- 静态数据做数据缓存
- 为了尽量减少Http握手挥手次数,开启Conection:keep-live
- 图片懒加载
- 视频音频的延迟加载
- 骨架屏
- 尽量减少JS和CSS文件的数量,保证Http请求不要太多
- 资源分服务器部署,虽然Http请求过多,但是加大了各服务器的处理能力,因为每个服务器最大请求量是5-7,如果多了会导致阻塞
- 减少DOM元素的刷新
- …
为什么必须要三次握手,四次挥手,多一次少一次不可以吗?
- 三次握手四次挥手是在保证连接安全的情况下客户端与服务器之间建立连接的最优方案
- 三次握手:
- 客户端向服务器发送连接请求(是否可以连接)
- 服务器响应给客户端可以连接
- 客户端通知服务器要建立连接
- 四次挥手:
- 客户端通知服务器请求已完毕,可以断开连接了,并把最后请求的资源发给服务器
- 服务器收到请求后,不能立即将资源处理出来,也不能不给客户端回复,否则客户端会认为服务器端响应超时,408,所以先告诉客户端等一等,我在准备数据
- 服务器发送完数据后告诉客户端我的数据发送完成了,可以随时关闭了
- 客户端这时需要告诉服务器确认关闭
- 我认为三次握手四次挥手就是能够保证两个端之间能够确认对方意图的前提下作的最优解,少一次不能完全理解对方的意图,多一次多余
各构造函数方法
Array30个
- Array.form
- Array.isArray
- arr.push
- arr.pop
- arr.shift
- arr.unshift
- arr.indexOf
- arr.lastIndexOf
- arr.concat
- arr.sort
- arr.reverse
- arr.toString
- arr.join
- arr.splice
- arr.slice
- arr.forEach
- arr.map
- arr.filter
- arr.some
- arr.every
- arr.reduce
- arr.reduceRight
- arr.incluse
- arr.keys
- arr.value
- arr.entries
- arr.flat
- arr.fill
- arr.find
- arr.findIndex
Object26个
- obj.toString()
- obj.valueOf()
- obj.isPrototypeOf()
- obj.hasOwnProperty()
- obj.PropertyIsEnumerable()
- Object.assign()
- Object.is()
- Object.create()
- Object.defineProperty()
- writable/configurable/enumerable/get()/set()
- Object.getOwnProperyDescriptor()
- Object.getOwnPropertyDescriptors()
- Object.getOwnPropertyNames()
- Object.getOwnPropertySymbols()
- Object.keys()
- Object.values()
- Refelect.ownKeys()
- Object.freeze()
- Object.isFreezen()
- Object.slat()
- Object.isSlated()
- Object.PreventExtensions()
- Object.isExtensionsable()
- Object.getPrototypeOf()
- Object.setPrototypeOf()
- Object.entries()
- Object.fromEntries()
Set6个
Set比数组的好处是:Set不能存在重复项(可用来做去重)
let set=new Set()
- set.size:数据项个数
- set.add(1):添加数据项
- set.delete(5):删除索引为5的值
- set.has(1):判断set中是否存在1值
- set.clear():清除集合
- set.forEach():遍历数组
Map7个
Map比Object的好处是:存在size个数,能够遍历每一项,且属性名可以是任何数据类型
let m=new Map()
- m.size:属性个数
- m.set(key,value):设置属性
- m.delete(key):删除某属性
- m.get(key):获取属性
- m.has(key):判断是否存在某属性
- m.clear():清空所有属性
- m.forEach((item,index)=>{},this指向):遍历每一个属性
Promise
Promise的方法?
- 静态方法5个
Promise.resolve(result)
:创建状态为resolve的实例Promise.reject(reason)
:创建状态为reject的实例let p1=Promise.all([promises])
:参数为promise实例的数组,如果不是,调用Promise.resolve()
转换- 成功:只有数组中所有promise实例状态为resolved,p1状态为
resolved
,值为按之前数组排序的各实例返回的结果值 - 失败:只要有一个失败,p1状态值为
rejected
,结果为错误原因
- 成功:只有数组中所有promise实例状态为resolved,p1状态为
let p1=Promise.any([promises])
:参数同上- 成功:只要有一个成功,p1状态值为
resolve
,值为返回的结果值 - 失败:只有全部结果是
rejected
,p1状态值才为rejected
,值为按之前数组排序各实例返回的原因
- 成功:只要有一个成功,p1状态值为
let p1=Promise.race([promises])
:参数同上- 成功/失败:所有的实例比赛,看哪个实例首先确认状态,哪个就是p1实例的结果
- 公有属性和方法4个
p1.then(onfulfilled,onrejected)
:两个参数都是函数,p1为resolved时执行第一个,p1为rejected时执行第二个p1.catch(onrejected)
:只捕获状态为rejected
的实例p1.finally(fn)
:成功和失败态都捕获- **
Symbol(Symbol.toStringTag):"Promise"
**调用toString的结果
- 实例私有属性2个
PromiseState
:存放实例状态,有pending/fulfilled/rejected
PromiseResult
:存放实例的结果值,pending状态下是undefined,或者失败的原因或成功的结果
创建Promise实例的方法五种?
new Promise((resolve,reject)=>{})
:创建Promise的实例Promise.then()
:执行的结果必是Promise实例Promise.reject/resolve()
:直接创建一个对应状态的实例Promise.all/any/race()
:执行的结果必是Promise实例async/await
:用async修饰的函数执行的结果必是Promise实例
如何做到项目中的Promise语法编译成ES5的语法?
@babel/preset
是用来将ES6语法转为ES5语法,只能转let/const,不能转这些ES6新增的类- 我们可以导入
@babel/polyfill
,它能转换Promise
等类 browlist
JSON
JSON对象的方法?
- JSON对象的stringify和parse方法可以实现对象的深拷贝,但是存在一些问题:
- 转布尔类型值会报错
- 属性值是
undefined/function/symbol
,属性名是symbol
类型的会消失 - 属性值是
RegExp/Error
类型的值会转为{} - Date对象变为字符串后,无法在通过parse转为Date
- 一旦出现套娃操作,(obj.obj=obj)就会报错
- 没问题的类型:
Number/String/Boolean/Array/普通对象
继承
继承的方式有哪几种?
- 原型链继承
- call继承
- 寄生组合继承
- ES6新增的extends继承
同步异步
- 同步:只有上一件事完成之后,才能进行下一件
- 异步:当执行到异步任务时,会开启新线程去执行它,同步上的任务可以继续执行
- 串行:多个请求之间存在依赖,只有上一个请求成功,才能发送下一个请求(第二个请求,需要依赖于第一个请求的结果)
- 并行:请求之间没有啥依赖,可以同时发送多个请求[一般会额外处理一些事情:等待所有请求都成功,统一做啥事]
js中的同步异步方法?
- [异步微任务:优先级高]7个
async/await
Promise.then/catch/finally
requestAnimationFrame
:实现JS动画IntersectionObserver
:监听DOM元素和视口交叉的信息MutationObserver
:监听DOM元素属性改变process.nextTick(){}:
node后台创建异步微任务queueMicrotask(){}
:前台创建异步微任务
- [异步宏任务:优先级低]5个
ajax/fetch
setTimeOut/setInterval
setImmidate
事件绑定
MessageChannel
响应式布局
什么是响应式布局,实现一个简单的响应式布局?
-
响应式布局就是创建一个页面,根据不同设备端的屏幕宽度,可以实现结构自动适配的一种布局方式
-
响应式布局有两种方案:移动端优先和PC端优先
- 移动端优先:默认样式以最小的手机端为标准:
用min-width
做判断,宽度越来越大 - PC端优先:默认样式以最大的PC端为标准:用
max-width
做判断,宽度越来越小
- 移动端优先:默认样式以最小的手机端为标准:
-
实现:
/*屏幕宽度小于991px,改变布局和样式*/ @media screen and (max-width:991px) { header { padding: 10px 20px; flex-direction: column; } .banner { padding: 150px 20px 50px; flex-direction: column-reverse; } .banner .image { max-width: 80%; margin-left: 0; } .banner .content h2 { font-size: 2em; } } //屏幕宽度大于992px并且小于1080px时改变布局和样式 @media screen and (min-width:992px) and(max-width:1080px) { } //屏幕宽度大于1080px时改变布局和样式 @media screen and (min-width:1080px) { }
HTTP
- 状态值:
- 0:请求未初始化
- 1:请求已建立,open()已执行
- 2:发送请求成功,send()已执行
- 3:正在响应
- 4:响应已完成
- 状态码:
- 1xx:响应处理类
- 2xx:处理成功类
- 3xx:请求重定向类
- 4xx:客户端错误
- 5xx:服务器端错误
http状态码详细?
- 1xx:响应处理类
- 100:继续请求
- 101:切换http版本
- 2xx:响应成功类
- 200:已发送
- 201:已接收
- 202:已创建
- 203:非授权信息
- 204:空内容
- 205:重置内容
- 206:部分内容
- 3xx:请求重定向类
- 300:多种选择
- 301:永久重定向
- 302:临时重定向
- 303:GET临时重定向
- 304:资源未修改
- 305:需要代理服务器
- 306:废弃
- 307:是否使用POST临时重定向
- 4xx:客户端错误
- 400:url格式错误
- 401:需要身份验证
- 402:还没用
- 403:拒绝响应
- 404:资源未找到
- 405:请求的方法被禁止
- 406:无法生成响应头
- 407:需要代理服务器身份验证
- 408:请求超时
- 409:资源状态冲突
- 410:资源已删除
- 411:必须存在
Content-length
字段 - 412:请求资源的前提条件不满足
- 413:请求的实体过大
- 414:请求的URL过长
- 415:请求的资源类型不允许
- 416:不满足期望的请求范围
- 417:不满足请求头的条件
- 5xx:服务器端
- 500:服务器内部错误
- 501:服务器拒绝请求
- 502:带宽错误
- 503:服务器维护或过载,无法响应
- 504:带宽超时
- 505:http版本不支持
http1.0/1.1/2.0版本发布时间?
- 1991->http0.9
- 1996->http1.0
- 1999->http1.1
- 2015->http2.0
http1.0/1.1/2.0版本区别(精简)?
1.0vs1.1
- 缓存处理:
- 1.0:
expires(强)
和last-modified(协商)
,浏览器if-Modified-Sience(协商)
- 2.0:
catche-Control(强)
和etag(协商)
,浏览器if-Node-Match(协商)
- 1.0:
- 错误处理:新增了许多状态码
- host头处理:当一台主机上有多台虚拟机时,同host区分
- 长连接:
connection:默认keep-alive
- 带宽优化:支持断点续传
1.1vs2.0
- header压缩:基于
encoder
让收发双方各存一份header files
- 二进制格式传输:1.1使用文本格式,2.0使用二进制格式(没有类型限制)
- 服务器推送:向服务器请求一个文件,与该文件关联的必要资源同时被发送过来
- 多路复用:1.0:用完即断,1.1:长连接,2.0:多路复用
http1.0/1.1/2.0版本区别?
-
http1.0和http1.1对比
- 缓存处理:http1.0用
expires
(强)和last-modified
(协商)来作为缓存判断的标准,http1.1引入了更多的缓存控制策略:cache-Control
(强)、etag
(协商),请求头有:if-Modified-Since
和if-Node-Match
- 错误通知:http1.1新增了24个错误状态响应码,如
- 409:Conflict,处理请求资源时冲突
- 410:Gone,表示服务器上的某个资源被永久性删除了
- 长连接:HTTP1.1中默认开启Connecton:keep-alive,一定程度弥补了HTTP1.0每次请求都要创建连接的缺点。
- 带宽优化:http1.1支持断点续传,即状态码是
206(Partial Content
) - Host头处理:
- 在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL不存在主机名(
hostname
)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers
),并且它们共享一个IP地址。 - HTTP1.1的请求消息和响应消息都支持Host头域,请求消息中如果没有Host头域,会报一个错(
400 Bad Request
)
- 在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL不存在主机名(
- 缓存处理:http1.0用
-
http2.0和http1.x对比
-
header压缩:
HTTP1.x
:的header带有大量信息,而且每次都重复发送。HTTP2.0
: 使用encoder来减少需要传输的header大小,通讯双方各自缓存一份header fields表,既避免了重复header的传输,又减小了需要传输的大小
-
服务端推送(server push):
-
http1.x
:向服务器请求啥文件,服务器就给啥 -
http2.0:
例如我的网页有一个sytle.css的请求,在客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到,不用再发请求了-
// 通过在应用生成HTTP响应头信息中设置Link命令 Link: </styles.css>; rel=preload; as=style, </example.png>; rel=preload; as=image
-
-
-
二进制传输(Binary Format):
HTTP1.x
:的解析是基于【文本】,基于文本的格式解析存在天然限制,要想做到健壮性需要考虑多个场景HTTP2.0
:的解析时基于【二进制】,只认0和1的组合,不需要考虑传输文件的格式,健壮性强
-
多路复用(MultiPlexing):
-
HTTP/1.0
:[用完就关]每次请求响应,建立一个TCP连接,用完关闭 -
HTTP/1.1
:「长连接」 若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞; -
HTTP/2.0
:「多路复用」一个连接上开启多个请求,某个请求任务耗时严重,不会影响到其它连接的正常执行;
-
-
http请求发生事情?
- url解析
- 缓存检查
- DNS解析
- 三次握手
- 基于http传输数据
- 四次挥手
- 浏览器底层渲染
浏览器渲染
浏览器渲染分为几种线程?
- GUI渲染线程[同步]
- HTTP线程:link/img/video/audio等[异步],script[同步]
- js引擎线程:渲染js代码的主线程,是一个单线程
- 定时器监听线程
- 事件触发监听线程
- webWorker
crp关键渲染路径的渲染步骤?
- 第一步:获取所有的HTML标签生成DOM树
- 第二步:获取所有的CSS代码生成CSSOM树
- 第三步:将DOM树和CSSOM树合并成render树
- 第四步:布局排列(layout)
- 第五步:绘制(painting)
- 第六步:回流(reflow),页面中元素的【结构、大小、位置改变时触发】
- 第七步:重绘(repaint),页面中元素【颜色,字体颜色改变时触发】
小程序
小程序中的页面跳转及传参方式?
-
页面跳转分为两种标签跳转和方法跳转
-
标签跳转:
<navgiator url="xxx" open-type="xxx">
,其中open-type的跳转方式有四种:navgiate
:保留原页面,跳转到非tabbar页面redirect
:删除原页面,跳转到非tabbar页面switchTab
:删除所有非tabbar页面,跳转到tabbar页面reLanuch
:删除所有页面,重新打开程序到某个页面
-
方法跳转:
wx.navgiateTo()/redirectTo()/switchTab()/reLanuch()
-
例如:
-
wx.navgiateTo({ url:"../../index?name='lili'" })
-
-
-
问号传参:
<navgiator url="xxx?name='lili'" open-type="xxx">
- 指定路径xxx用
onLoad
事件函数接收参数:onLoad(options){options就是传入的参数对象}
- 指定路径xxx用
组件的生命周期?
- 组件的生命周期分为两种应用生命周期和页面生命周期
- **应用生命周期:**5个
onLanuch
:应用初始化时触发onShow
:应用加载完成或从后台切换到前台是触发【数据会更新】onHide
:应用从前台切换到后台时触发onError(err)
:应用报错时触发onPageNotFound
:第一次打开,默认的页面没有找到时触发
- **页面生命周期:**6个
onInit
:百度小程序独有,页面初始化时触发onLoad(options)
:页面加载时触发【可用来获取参数】onShow
:页面加载完成,或从后台跳转到前台,或从隐藏切换到显示时触发onReady
:页面加载完成时触发onHide
:页面被隐藏或从前台切换到后台时触发onUnLoad
:页面删除时触发
- **应用生命周期:**5个
小程序的监听事件?
- 监听事件8个
onPullDownRefresh
:下拉页面时触发onReachBottom
:上拉触底时触发onShareAppMessage
:分享内容时触发onShareTimeLine
:分享到朋友圈时触发onAddToFavorites
:收藏时触发onPageScroll
:页面滚动时触发onResize
:页面大小变化时触发,比如旋转屏幕onTabItemTap
:轻击tab按钮时触发
小程序常用API
setData({name:'lili'})
:修改或创建响应式数据getData("name")
:获取name数据let xxx=require('./index')
:导入module.exports={}
:导出wx.request({url:"",method:"",header:{},data:{},success:(response)=>{},faild:(reject)=>{}})
请求后台数据wx.showToast({title:"",icon:"",success:{},duration:})
:弹出信息框wx.showLoading({hideLoading(){}})
:它能够等待信息获取成功后再调用hideLoading()方法关闭消息框
数据缓存API
wx.setStorageSync('key','value')
:同步设置缓存let key=wx.getStorageSync('key')
:同步获取缓存wx.removeStorageSync('key')
:同步删除缓存let res=wx.getStoreInfoSync()
:同步获取缓存对象wx.clearSroage()
:清除小程序中的缓存- 带sync是同步的,不带sync是异步的
上传图片或视频
-
wx.chooseImage({Object Object})
:上传图片-
wx.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: (res)=> { // tempFilePath可以作为img标签的src属性显示图片 const tempFilePaths = res.tempFilePaths } })
-
success后必须跟的是箭头函数,否则里面的this找不到wx
-
-
wx.chooseVideo({Object object})
:上传视频
缓存
- 缓存一般包括强缓存、协商缓存、数据缓存
- **强缓存:**静态页面一般可以做强缓存
- 协商缓存:为了避免客户端与服务器端的数据偏差,可以做协商缓存
- **数据缓存:**数据缓存又分为了`cookie/localStorage/SessionStorage
cookie
:有期限的存储在浏览器内存中localStorage
:存储在硬盘中,关闭页面还在SessionStorage
:存储在内存中,关闭页面就不在了
cookie的API:2个
document.cookie
:获取cookie中所有数据document.cookie="name=sjh"
:向cookie中设置名=值对类型的cookie
localStorage的API:4个
localStorage.setItem('key',value)
:向本地缓存添加一个键值对localStorage.getItem('key')
:获取一个本地缓存中的值localStorage.removeItem('key')
:删除一个本地缓存中的值localStorage.clear()
:清除所有本地缓存
sessionStorage的API:4个
sessionStorage.setItem('key','value')
:向会话存储中设置一个缓存sessionStorage.getItem('key')
:获取会话存储中的一个值sessionStorage.removeItem('key')
:删除会话存储中的一个值sessionStorage.clear()
:清除会话存储中的缓存
vue
vue项目的优化?
-
代码层优化
- v-if和v-show合理使用
- v-for遍历添加key,且避免同时使用v-if
- 图片懒加载
- 路由懒加载/分类打包
- 第三方插件按需导入
- 服务端渲染SSR 或 预渲染(骨架屏)
- 用vuex做缓存
-
webpack层优化
-
对小图片进行base64压缩
-
html、js、css文件压缩
-
关闭SourceMap
-
开启gzip压缩
-
vue2
vue3
vue3与vue2的区别?
- vue3推崇函数式编程,vue2推崇面向对象编程
- vue3重写了虚拟DOM实现,跳过静态节点,只关注动态节点
- vue3实现了过滤,性能优化(只导入但未使用的文件打包时不加载)
- vue3支持根节点存在多个节点
- vue3实现了传送门
- vue3可以创建异步节点
- vue3对Typescript更友好
- vue3使用Compisition API(聚合式API),vue2使用options API(选项API)
- vue3的响应式数据拦截,更多的采用Proxy实现
defineProeprty与Proxy的区别?
- defineProperty()做劫持
- 应用在vue2和vue3中
- 通过将传入的对象的每个属性做get和set劫持实现监听
- 如果某个属性值仍然是对象或数组,需要使用递归的方式做深劫持
- 数组的每一项不会做劫持,但是需要重写数组的七个方法
- Proxy做劫持
- 应用在vue3中
- 可以直接代理整个对象,不需要再迭代每个属性做劫持
- 对数组中的每一项也会做劫持
- 不仅可以做get、set劫持:
get/set/has/ownKeys/getPrototypeOf/setPrototpyeOf/defineProperty/deleteProperty
vue2实例的创建步骤?
- 初始化props
- beforeCreate()->没有生成this,没有data、methods、el
- 挂载数据/方法
- created()->已经生成了this,data、methods、el(但el还没有绑定DOM元素)
- beforeMount()->还没有挂载
- 渲染
- Mounted()->数据已经渲染到页面上了
setup()钩子函数?
- 发生在props初始化之后,beforeCreate之前
- setup(props)中没有this
- 可以基于第一个形参接收props传入的值,但是只读(readonly)的
- 代替了之前的new Vue({options API}),直接导出setup()函数
- 函数中return的是一个对象,对象中的值可以在视图中使用
vue3的10+响应式API?
- ref:创建一个响应式状态值
- reactive:创建一个存放多个响应式状态值的对象
- toRef:将reactive创建的一个响应式状态值转为ref类型的值(目的:能够在视图中直接使用)
- toRefs:将reactive创建的响应式状态值对象转为ref类型的值
- unRef:将响应式状态值转为非响应式
- readonly:将状态值转为只读的
- computed([状态名],[callback]):创建一个计算属性,callback返回的值就是状态名的值
- watch([监控的值],[callback]):监控某个状态值,执行callback函数
- watch([RefImpl实例],[callback],[config]):监控refImpl实例
- watch([Proxy对象],[callback],[config]):监控整个Proxy对象
- watch(()=>{Proxy.xxx},[callback],[config]):监控Proxy对象的某个属性值,必须第一个参数是函数,在return要监控的属性
- watchEffect([callback]):callback中存在哪些状态值,就监控哪些状态值
- isRef:判断是不是ref创建的状态值
- isreadonly:判断是不是只读的
- isProxy:判断是不是Proxy类型的对象
- isreactive:判断是不是reactive创建的状态值
周期函数?
beforeCreate()
->setup()
- Created()->setup()
- beforeMount()->onBeforeMount()
- mounted()->onMounted()
- beforeUpdate->onBeforeUpdate()
- updated->onUpdated()
- beforeDestory()->onbeforeUnMount()
- destoryed()->onUnMounted()
css
flex
- 被flex修饰的DOM元素被称为container容器
- container里面的子节点都被称为项目
flex的常见样式?
container容器的样式:7种
display:
:块级/行内弹性盒flex/inline-flex
flex-decuration:
:主轴方向row(默认)/row-reverse/column/column-reverse
flex-wrap:
:是否换行nowrap(默认)/wrap/wrap-reverse
flex-flow:decutation wrap
:方向和换行的复合写法justify-content:
:主轴方向项目排列方式flex-start(默认)/flex-end/center/space-between/space-around/space-evenly
align-items:
:侧轴方向项目排列方式flex-start/flex-end/center/baseline/strech(默认)
align-content:
:多行情况下项目整体的排列方式flex-start/flex-end/center/space-between/space-around/space-evenly/stretch
项目的样式:6种
order:0
:定义项目排列顺序,值越小越往前flex-grow:0
:定义项目增长当前行空余空间的几份,默认都是0flex-shrink:0
:0表示不缩小,1表示跟着容器缩小而缩小flex-basis:10px
:项目在主轴方向大小,比宽高优先级高flex:0 1 auto
:grow shrink basis的复写flex:1
:->1 1 0%:所有项目平分,且跟着容器缩放而缩放
align-self:
设置单个项目与其他项目在侧轴上的不同auto
:默认值,继承父级的aligin-items,如果没有就是stretchflex-start/flex-end/center/base-line/strech
文本溢出用…
单行文本溢出?
overflow:hidden;
text-overflow:ellipisis;
white-space:no-warp;
多行文本溢出?
overflow:hidden;
text-overflow:ellipisis;
display:-webkit-box
-webkit-box-orient:vertical
-webkit-line-clamp:2