JavaScript
1.js的数据类型
基本数据类型:Number、String、Boolean、Null、Undefined、Symbol、Bigint
引用数据类型:Object、Array、Function
2.如何判断数据类型
typeof:局限性(null,引用数据类型)
instanceof:局限性(基础数据类型)只能判断两个对象是否在同一原型链关系上
Array.isArray(变量):局限性(只能是数组)
Object.prototype.toString.call(变量)
返回格式形如:[object Array],[object RegExp]、[object Date]等
3.js中的继承
1. call继承: 用call或apply在子类构造函数中调用父类构造函数
优点:在于可以在子类构造函数中像父类构造函数传递参数。父类的引用属性不会被共享
缺点:子类不能访问父类原型上定义的方法,因此所有方法属性都写在构造函数中,每次创建实例都会初始化
2. 原型继承:将父类的实例作为子类的原型
缺点:父类的所有引用属性会被所有子类共享,更改一个子类的引用属性,其他子类也会受影响
子类型实例不能给父类型构造函数传参
3.组合继承:使用原型链继承原型上的属性和方法,而通过构造函数继承实例属性,这样既可以把方法定义在原型上以实现重用,又可以让每个实例都有自己的属性
4.class继承:组合继承的语法糖
缺点:新语法,只要部分浏览器支持,需要转为 ES5 代码。
4.原型链
当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型中寻找也就是构造函数的显示原型即原型对象。原型对象上没有会去原型对象的隐式原型属性中寻找,原型链上逐级向上查找
5.闭包
闭包 = 函数 + 周围状态(环境的)的引用 ,称之为闭包结构
简单说就是如果一个函数引用了它外部的变量,则这个函数和这些外部变量一起构成了闭包结构
闭包在开发中的作用是:封闭数据,提供操作。
闭包在我们的代码无处不在。
6.如何判断this的指向
- 总是代表着它的直接调用者,如obj.fn,fn里的最外层this就是指向obj
- 默认情况下,没有直接调用者,this指向window
- 严格模式下(设置了’use strict’),this为undefined
- 当使用call,apply,bind(ES5新增)绑定的,this指向绑定对象
箭头函数没有this,去外层作用域找this
7.call apply bind的使用
函数名.call(this指向,参数1,参数2,参数3...)
函数名.apply(this指向,[参数1,参数2,参数3...])
函数名.bind(this指向,参数1,参数2,参数3...)
8.数组常用api
push pop
shift unshift
splice slice
reserve join
concat sort
forEach some
every filter
map reduce
find findIndex
indexOf
9.reduce的使用格式
arr.reduce((累加器,当前元素,当前元素索引,原数组) => {}, 累加器初始值)
10.什么是回调地狱,如何解决
是一个现象,例如一个异步请求依赖上一个或多个异步请求结果,而下一个异步请求又依赖这一次的异步请求结果,环环相扣依赖形成回调地狱
使用promise处理异步请求,成功执行.then,失败穿透到最后执行.catch
穿透指.then只写一个回调参数或者第二个参数为 reason => {throw reason}
缺点, 不够简洁
终极方案: 使用async await
11.promise的使用
ES6提供Promise构造函数,我们创造一个Promise实例,Promise构造函数接收一个函数作为参数,这个传入的函数有两个参数,分别是两个函数 resolve和reject作用是,resolve将Promise的状态由未成功变为成功,将异步操作的结果作为参数传递过去;相似的是reject则将状态由未失败转变为失败,在异步操作失败时调用,将异步操作报出的错误作为参数传递过去。
实例创建完成后,可以使用then方法分别指定成功或失败的回调函数,比起f1(f2(f3))的层层嵌套的回调函数写法,
- 对象不受外界影响,初始状态为pending(等待中),结果的状态为resolve和reject,只有异步操作的结果决定这一状态
- 状态只能由pending变为另外两种的其中一种,且改变后不可逆也不可再度修改,
即pending -> resolved 或 pending -> reject
12.new的背后做哪些事情
1.创建一个空对象
2.空对象执行构造函数的原型对象
3.修改构造函数this指向空对象,执行函数体
4.返回该对象
13.防抖和节流
防抖应用场景:input
持续触发不执行,不触发间隔时间后执行
节流应用场景:监听滚动事件
持续触发也执行,执行频率是间隔时间
14.高阶函数
接收函数作为参数或者是返回值是函数
map、filter、every、some、reduce、forEach、
15.函数柯里化
只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
主要应用:参数复用
lodash
const lodash = require('lodash') const newFn = lodash.curry(fn)
16.for in和for of的区别
for in是遍历所有可枚举属性,包括原型上的,
- 遍历对象返回的属性名和遍历数组返回的索引都是 string 类型;
- 某些情况下,可能按随机顺序遍历数组元素;
- 不推荐在数组中使用 for in 遍历
for of 用来遍历拥有迭代器对象的集合
- es6 中添加的循环遍历语法;
- 支持遍历数组,类数组对象,字符串,Map 对象,Set 对象;
- 不支持遍历普通对象;如果要遍历对象,可与 Object.keys 配合
- 遍历后输出的结果为数组元素的值;
- 可搭配实例方法 entries(),同时输出数组的内容和索引;
17.递归及应用场景
函数内部调用自身
应用场景: 数组扁平化 , 深拷贝
18.eventloop事件循环
JS 代码的执行分为同步任务和异步任务,
当碰到同步代码时,直接在执行栈中执行,
当碰到异步任务并且时机符合时(例如定时器的时间到了),
就把异步代码添加到任务队列中,
当执行栈中的同步代码执行完毕后,
才去任务队列中把异步代码拿到执行栈中执行,
这种反复执行任务队列的过程就是 Event Loop
19.深拷贝和浅拷贝
20.垃圾回收机制
21.await async的使用方式
22.js延迟加载的方式
1.在<script> 元素中设置 defer 属性,脚本立即下载,在页面已加载之后运行
2.为 <script>标签定义了 async属性,不让页面等待脚本下载和执行,从而异步加载页面其他内容,一定会在页面 load 事件前执行 async 属性仅适用于外部脚本
3.动态创建DOM--document.createElement("script")创建新的script标签并赋src值,达到按需加载
4.使用setTimeout延迟
5.jQuery的getScript()方法--$.getScript('a.js',funcion(){})成功获取文件后执行回调
6.js外部引入的文件放到页面底部
23.跨域问题及解决方案
24.事件冒泡和事件捕获
25.事件委托
26.如何添加和删除事件
添加:
内联式: <button oncLick="..."></button>
document.getElementById('btn').onclick = () => {}
document.getElementById('btn').addEventListener('click',函数名)
删除:
document.getElementById('btn').onclick = null
document.getElementById('btn').removeEventListener(函数名)
网络请求
1.https和http的区别
无状态表示数据包的发送、传输和接收都是相互独立的
http(不安全): 无状态连接
明文传输(传输过程中,任何人都可能截获/修改/伪造);
不会验证通信方身份
不会验证报文完整性
默认端口80
https: http + 使用传输层安全性(TLS)或安全套接字层(SSL)建立连接
加密: 防止被监听,被跟踪, 被窃取
数据一致性: 数据完整
身份认证: 防止中间人攻击
默认端443
2.常见http的状态码
3.描述输入url地址到网页展示的过程
1.DNS解析获取服务端ip
浏览器缓存 -> hosts文件或系统缓存 -> 外部缓存 -> 对应的域名服务器查找并解析
2.建立连接,三次握手
C -> S 发送一个包, C进入等待状态, S知道C能 [发]
S -> C 发送确认包, S进入等待状态, C知道S能 [发] [收]
C -> S 发送确认包, C和S都进入确认状态 S知道C能 [收]
3.发送请求(请求报文)
4.响应数据(响应报文)
5.断开连接,四次挥手
C -> S 发送Fin标记包,告诉浏览器可以关闭连接,C不用发送数据了,但是还可以接收, C进入最终等待状态
S -> C 发送一个确认包, 告诉C收到了关闭请求,但是还没有准备好关闭, S进入关闭等待状态 C进入还在最终等待状态
S -> C 服务端准备好关闭连接时,发送Fin标记包,S 进入等待确认状态
C -> S 客户端收到后再发送确认包, 进入关闭倒计时,S收到后就进入了关闭状态, C倒计时结束后也进入关闭状态
6.渲染页面
4.本地持久化的方式和区别
localStorage | 不会自动把数据发送给服务器 | >5M | 永久有效 | 同源窗口共享 |
sessionStorage | >5M | 浏览器关闭前有效 | 不在不同浏览器窗口共享 | |
cookie | 始终在同源的http请求中携带 | <4K | cookie过期前有效 | 同源窗口共享 |
5.get请求和post请求的区别
本质都是tcp连接,无差别
get:
长度限制2048字节,数据暴露在地址栏,请求会保存在浏览器历史记录中
post:
长度无限制, 数据放在请求体中
6.http的协议的三个内容
请求行
头部
请求体
7.请求头中的contentType有什么用处
向接收方说明传输资源的媒体类型
CSS + HTML
1.如何减少重绘和回流
2.居中
Vue
1.单个组件的生命周期钩子
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- activated
- deactivated
- beforeDestroy
- destroyed
- errorCaptured
activated, deactivated 是组件keep-alive时独有的钩子
errorCaptured:当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
2.哈希路由和history路由的区别
3.哈希路由和history路由的原理
4.父子组件的生命周期钩子
加载渲染过程: 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
更新过程: 父beforeUpdate->子beforeUpdate->子updated->父updated
销毁过程: 父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
5.v-model和.sync的对比
相同点: 都是语法糖,都可以实现父子组件中的数据的双向通信。
v-model一个组件或输入框只能绑定一个 .sync可以有多个
<Input v-model="sum">
<!--默认等效于下面这行-->
<Input :value="sum" @input="(value)=>{sum=value}">
//子组件
<input :value="sum" @input="(e)=>{$emit('input',e.target.value)}"/>
//父组件
<Input :foo.sync="sum">
<!-- 等效于下面这行,那么和v-model的区别只有事件名称的变化 -->
<Input :foo="sum" @update:foo="(value)=>{sum=value}">
//子组件
this.$emit('update:foo',value)
6.vuex的基本使用步骤
7.组件之间传参方式
props、emit(最常用的父子通讯方式)
事件总线 EventBus
Vuex 状态管理
ref (常用于父组件调用子组件的方法)
$attrs/ $listeners
provide / inject (祖先及其后代传值)==>常用一些多个组件嵌套封装,一个顶层组件内部的后代组件需要用到顶层组件的数据就使用这种方式
8.vue路由钩子beforeEach的参数
接收一个回调,回调有3个参数
- to: 即将要进入的目标路由对象
- from: 当前导航正要离开的路由
- next: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next() : 进行管道中的下一个钩子。
next(false) : 中断当前的导航
next('/') 或者 next({ path: '/' }) : 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任何用在 router-link 的 to prop 或 router.push 中的选项。
next(error) : (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
9.vuex的getter的作用
getter用于对state里面的数据进行处理 并形成新的数据 也就是说 getter不会更改state里面的数据
相当于vue里面的computed属性 并且 会跟着 state的改变而改变
10.mutation和action的使用区别
Mutation 必须是同步函数
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
11.计算属性和watcher的使用区别
12.vue2中v-model是一个语法糖,那具体是怎么实现的
实际上就是 $emit('input') 以及 props:value 的组合语法糖
13.v-if和v-show的区别
v-if的原理是根据判断条件来动态的进行增删DOM元素,v-show是根据判断条件来动态的进行显示和隐藏元素,频繁的进行增删DOM操作会影响页面加载速度和性能
v-if能和v-else连用进行分支判断,v-show是不能和v-else连用的,如果出现多种条件场景的情况下,可以使用v-if来进行判断
14.key的作用
为了高效的更新虚拟dom,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少dom操作量,提高性能。
15.vue2常用指令有哪些
v-bind(:)、v-on(@)、v-for、v-if、v-else、v-show、 v-model
16.vue2和vue3的区别
17.vue2中过滤器是怎么使用的
18.vue2中如何自定义指令
19.vue2中vue.use是怎么用的
安装Vue.js插件。如果插件是一个对象,必须提供install方法。如果插件是一个函数,它会被作为install方法。调用install方法时,会将Vue作为参数传入。
install方法被同一个插件多次调用时,插件也只会被安装一次。
20.vue2中$nextTick
数据更新是同步的,视图更新是异步的,当我们数据更新完毕,视图的更新还处在任务队列中, 如果我们频繁更新数据,Vue 不会马上更新视图,通过将更新操作放入队列,同时进行去重处理,提高性能, 最后,我们需要通过 nextTick 的回调函数,告诉 Vue 底层,当视图更新完毕帮我们执行 nextTick 的回调函数, 完成我们的需求