1.instanceOf实现原理
(1)概念: instanceof是用来判断实例对象的原型链上是否存在构造函数的prototype属性,若存在,则返回true值。(通过实例对象的__proto__属性是否全等于构造函数的prototype属性)
(2)实现原理: 利用原型和原型链,每一个对象都有一个__propo__属性,每一个构造函数都有prototype属性,当我们对象的原型链存在显示原型prototype时,可以确定它们之间存在关系,即返回true。
(3)代码实现:
实例对象通过__proto__属性逐层向上寻找构造函数的prototype属性,若找到原型链顶端null还未找到,则退出递归循环。
2.Render函数
(1)概念: Render函数是一个渲染函数,它的参数createElement也是一个函数,跟template一样是用来创建模板的,render的方式其实是通过createElement()进行虚拟DOM的创建,template是类似于html一样的模板来进行组件的封装,返回值为Vode。
3.Vue的VDOM(虚拟DOM)的了解
(1)概念: 虚拟DOM用来描述视图的结构,在视图的每个组件都有一个render函数,每个render函数都会返回一个虚拟DOM。
(2)作用: 是用来解决渲染效率的问题。因为在渲染视图以及视图依赖数据的更新时都会调用到render函数,在渲染时若每次都使用真实DOM来创建、更新会带来极大的性能消耗,所以使用虚拟DOM来代替真实DOM是用来解决渲染效率的问题。
4.MVC和MVVM的了解
MVVM
(1)概念: MVVM(M:模型(数据),V:视图,VM:视图模型)是近几年前端较热门的一个模式,通过视图模型(主要用来处理业务逻辑)作为桥梁,当数据发生变化时视图也会变化,当视图发生变化时数据也会变化。
(2)作用: MVVM主要是用来实现数据双向绑定的,通过数据绑定实现数据驱动视图,通过DOM事件监听实现视图驱动数据。MVVM的优点是用来分离视图和模型,可以将重复的业务逻辑写在模型中,使得让更多的视图来共用,可以实现数据双向绑定,当模型的数据发生改变时,不需要手动操作DOM元素去更改在视图上的值,改变数据后,视图上的值会自动改变。
MVC
(1)概念: MVC(M:模型(数据),V:视图,C:控制层)控制层:用来处理用户的输入,负责改变模型的状态并选择适当的视图来显示模型的数据。MVC模型改变视图,但是视图改变不能响应改变模型。
5.v-if与v-show的区别使用
相同点: 都是用来控制DOM元素的显示或者隐藏
不同点:
v-if是若条件不成立则销毁DOM元素,而v-show条件不成立将DOM元素隐藏(display:none)
v-if用于切换频率较低的场景,而v-show用于切换频率较高的场景。
v-if有更高的切换消耗,v-show不管初始条件是什么都会被渲染,有更高的初始渲染消耗。
6.原型与原型链
该图的流程: Person构造函数身上的实例对象plan1具有__proto属性,它指向构造函数Person指向的prototype原型对象,在prototype原型对象身上也有一个__proto__属性,因为他也是一个对象,他指向object的原型对象。
(1)概念:
原型具有显示原型和隐式原型,显示原型是指构造函数的prototype指向原型对象,隐式原型是指构造函数的实例对象的__proto__属性指向构造函数的原型对象。
__proto__是每个对象都有的属性,prototype是每个构造函数都有的属性
原型: 创建一个实例时会自动关联另一个原型。
原型链: 当访问一个对象的属性时,会通过对象身上的__proto__属性隐式原型去寻找构造构造函数的显示原型,若还未找到,则继续通过构造函数的__proto__属性隐式原型去寻找object的显示原型,像这样逐层向上查找的链式结构成为原型链。
7.栈与堆的理解
栈中存储的是基本数据类型,堆中存储的是引用数据类型。
若存储的是一个引用数据类型,首先将变量的值存入堆中的值中,堆中会自动生成一个地址值,栈中的值会指向堆中的地址值,栈也会生成一个地址值指向变量。若将变量的值赋值给另外一个变量的话,其实是将变量在栈中的值指向另外一个变量,若发现值一致,则会将变量在栈中的地址值指向另外一个变量(新增属性,也是在{}内新增,对象判断为false),所以两个变量指向指向同一个栈中的地址值,一个变量修改,另一个变量也会跟着改变。
若存储的是一个基本数据类型,首先将变量的值存入栈中的值中,栈中会自动生成一个地址值。若将变量的值赋值给另外一个变量,其实是将变量在栈中的值指向另外一个变量,栈中发现值一致时,不会再开辟一个空间,而是将变量的地址值指向另外一个变量。但另外一个变量修改了值,栈中会再开辟一个新的空间,将值存入新开辟的栈中的值内,同时生成一个新的地址值指向另外一个变量,所以两变量指向不同的地址值,改变值互不影响。
8.vue中data为什么是一个函数
因为是一个函数的话,函数会构成作用域,使得每个组件实例都有自己的作用域,从而实现组件之间相互独立,若返回的是一个对象,对象是引用数据类型,会造成数据污染,使得所有组件共用一个data,从而组件间相互影响数据。
9.v-for与v-if的优先级
v-for的优先级大于v-if,建议不要将v-for与v-if作用于同一个元素上,这样在每次循环的时候都会判断一次条件,会造成性能的浪费。
(1)可以在computer中将不符合条件的元素过滤出再进行循环。(filter)
(2)可以在外层在套一层元素,在外层中v-if判断,在内层v-for循环。
10.watch和computed区别
(1)computer计算属性: 拥有依赖缓存特性,当依赖的数据发生改变时,则会重新计算属性,当依赖的数据没有发生改变是,则会从缓存中直接读取。例:购物车中的总价是通过单价和数量计算出,若单价和数量改变则重新计算总价值。
(2)watch监听属性: 监听数据的变化,在数据的变化可以做相应的操作。
(3)总结: computer默认第一次加载开始监听,watch默认第一次加载不做监听,将immediate设为为true第一次加载开始监听。computer需要return返回值,watch不需要。computer内不能做异步操作,watch内可以做异步操作。
11.vuex是什么
vuex是集中式数据状态管理的仓库,用于公共数据状态的管理
使用场景: 用于多个组件依赖同一状态
属性:
state:用来存放公共数据的地方
getter:与computer用法一致,相当于state的计算属性
action:用来处理业务逻辑,可以异步执行
mutations:唯一修改state值得地方,同步执行
module:对vuex模块化处理
基本流程:
批量使用getter和state
12.vuex刷新页面会导致数据消失
(1)为什么: 因为刷新页面会重新创建一个vue实例,vuex是挂载在vue实例上的,导致页面刷新,vuex内的数据被重新赋值。
(2)解决方法: 做数据持久化处理,将数据存储在浏览器缓存中。将vuex的数据存储在sessionStorage中,或者安装vuex-persistedstate,在store.js引入,默认存储在localStorage。
13.cookies、sessionStorage、localStorage的区别
存储空间:cookie存储空间4kb,sessionStorage、localStorage有5M
有效期:cookie若设置有效时间,时间到了被销毁,即使浏览器被关闭,若没有设置有效时间,则关闭浏览器销毁(用户的登录信息,token令牌)
sessionStorage关闭当前页面、浏览器后自动销毁(临时账号登录,退出登录需再次校验)
localStorage永久保存,浏览器关闭后不会销毁,除非手动删除 (可以用来统计页面访问次数)
14.前端数据防篡改
(1)防止用户篡改数据:禁用F12和shift+ctrl+i
15.介绍下vue的生命周期
创建阶段->挂载阶段->运行阶段->销毁阶段
beforeCreate(创建前):实例创建前,该阶段不能访问data、method
create(创建后):实例创建后,能访问data,method,做必要请求的调用
beforeMounted(挂载前):组件未挂载到容器,操作页面数据没效果
Mounted(挂载后):组件挂载到容器,操作页面数据有效果
(当视图层所应用的data更新时,触发钩子函数beforeUpdate和Updated)
beforeUpdate(更新前):数据更新前,data数据是最新但未更新到页面上,页面与数据不同步
Updated(更新后):数据更新后,页面与数据同步
beforeDestroy(销毁前):data、method还可以使用,清除计时器,取消订阅与发布
Destroyed(销毁后):组件完全销毁,无法使用数据、方法等
通过Keep-alive包裹的组件具有activated和deactivated两个生命周期
activated:组件被激活时触发,每次Keep-alive被激活时调用,若需要在进入页面获取最新数据,应在此阶段获取,充当与created的效果
deactivated:组件被停用时调用
16.父子组件的生命周期执行顺序
(1)挂载时: 父组件会在beforeMounted先挂载子组件再去挂载父组件
(2)更新阶段:若父组件的值影响到子组件的值,父组件会等待子组件重新渲染后再进行更新
子组件的生命周期都会被先结束,父组件才会结束。先由父到子,再由子到父
17.Keep-alive的作用与原理
原理: 通过Vnode进行存储,对组件进行缓存
作用: 保留组件状态、避免页面重新渲染,对组件进行缓存。例:淘宝通过模糊搜索查询到商品,用户查找到对应的商品会返回搜索页继续进行查找,反复操作会导致组件重新渲染并重复发送网络请求,可以使用Keep-alive将组件进行包裹,对组件进行缓存,保留组件状态,从而避免页面重新渲染,提高性能。
使用: 在页面中通过include/exclude对组件进行匹配缓存或通过路由组件meta属性使组件进行缓存
18.get和post的区别
get请求携带参数在URL路径后面,post请求携带参数在请求体内
get请求URL有长度限制以及只能传ASCII字符,post请求没有URL长度限制可以传入更多的数据类型
get请求参数会被保留在浏览器历史记录中,post不会
get请求下只能使用params,post可以使用data或params
data与params的区别
params是放在URL路径后,data是放在请求体中。 params是在请求中看得到的,data是在请求中看不到的。
params与query的区别
在路由传参中,params只能和name搭配使用,不能与path搭配使用,query都可以
params传参时刷新页面参数会消失,query不会
动态路由
路由路径中配置占位符
params传参
声明式导航: router-link to="/list/123/zhangsan"
获取值: this.$route.params.id
query传参
声明式导航: router-link to="/list?id=123"
获取值: this.$route.query.id
19.防抖和节流
相同点: 都是防止某一个时间频繁触发
防抖:取消规定前的请求,合并请求(input输入框)
节流:在规定时间只触发一次函数调用(短信验证码)
防止多次点击下载
20.重排与重绘
重排:当DOM元素发生布局修改,会重排
重绘:当DOM元素发生样式修改,会重绘
避免重排和重绘:
(1)创建class类名,不使用行内样式style
(2)避免大量使用元素hover
(3)避免使用table布局
21.宏任务与微任务
执行顺序:主线程->微任务->宏任务
异步任务分为:微任务和宏任务
js是单线程进行的,只有当前一个任务执行完毕才会执行后一个任务,遇到异步任务会进入到任务队列中,等到主线程的任务结束,从任务队列取出任务放到主线程中进行,在主线程不断重复获取任务、执行任务成为事件循环
微任务:Promise.then/.catch(promise里面的代码是同步的) async/await
宏任务:定时器(setTimeout延时器与setInterval定时器)
22.闭包是什么
闭包是什么:闭包就是函数嵌套函数,内部函数能访问到外部函数的作用域,就是闭包
如何产生闭包:内部函数访问外部函数的变量就会产生闭包
闭包的好处是什么:避免全局变量的污染,延长变量的生命周期
闭包的缺点是什么:闭包中的局部变量,会一直保存在内存中,会导致内存泄漏
内存泄露:
不再用到的变量没用及时得到释放,导致内存长期被占用,造成系统内存的浪费
(1)尽量减少使用全局变量,因为全局变量不会被回收
(2)闭包中的局部变量会一直保存在内存中,将闭包引用外部函数的变量赋值为null
23.ES6新特性
(1) var、let、const
var声明的变量存在变量提升,可以在声明变量之前使用,值为underfine,可以重复声明变量
let声明的变量具有块级作用域,暂时性死区(在声明变量之前该变量都不可用,到声明变量那一行,变量可以使用),不可以重复声明变量
const声明的变量值不可改变且声明变量就要赋值,具有块级作用域
(2) 解构赋值
对象变量名与属性名一致,可以获取该值,用来获取res的值
数组是按照顺序取值,由它的位置决定值
(3) 拓展运算符(...)
将数组的值以逗号隔开,将对象的属性值都拿出
(4)模板字符串
以 写入,可以在${}内写入js语法
(5)箭头函数
(6)promise:
1.promise是用来解决回调地狱的最佳选择,(回调地狱就是嵌套回调问题,一个函数的返回值依赖上一个函数的返回值),因为promise只有两种结果,要么成功要么失败。
2.promise有三种状态:pending(进行中)、flfilled(已成功)、rejected(已失败)
状态只有两种可能从: p->f 或 p->r
3.promist有两个参数(reject,resolve),一个是成功返回reject,一个是失败返回resolve
4.通过async和await来操作promise
async和await是用来将异步转为同步的 操作,是用来解决.then链式调用的最佳方案,但是async和await无法捕获到promise的err值
async修饰的函数返回一个promise对象,await修饰的是promise对象的.then()中的值
-
promise.prototype.finally():无论结果如何都会执行
promise.prototype.all():只有当状态都为fulfilled(已成功)时,状态为fulfilled(已成功),若其中一个为rejected(已失败)则状态为rejected(已失败)。
promise.prototype.race():接受多个promise实例,当其中一个实例发生状态改变,其余的也会跟着改变。
24.深拷贝与浅拷贝
浅拷贝:浅拷贝如果拷贝的是原始类型,那就是拷贝的值,如果是引用类型,则拷贝的是引用地址,指向的是同一地址,所以修改值会改变
赋值、concat、object.assign()
深拷贝:深拷贝是将整个对象拷贝出来,在堆中创建一个新的区域存放该对象,修改值不会互相改变,指向不是同一地址
JSON.stringfiy/parse(会忽略underfine的值,原型链上的值或对象为函数时无法拷贝,)、lodash(第三方库)的clonedeep方法
25.路由中hash和history的区别
hash路由:URL地址后面带一个#,每次切换路径时,通过监听hashChange事件查看#后面更改哪个路径,根据hash的变化更换页面的锚点,不会刷新页面。
history路由:URL需与后端保持一致,否则会报错。
刷新页面时,hash 模式可以正常加载到 hash 值对应的页面,而 history 没有处理的话,会返回 404,一般需要后端将所有页面都配置重定向到首页路由。
26.route和router的区别
route:route是每一个路由都有的一个路由对象,具有URL解析的信息以及该路由的信息(路径、名称、参数)
router:是VueRouter的一个对象,是一个全局的对象,具有所有路径
this.$router.push({path:'/'}):向history栈中添加一个路由
this.$router.replace:替换当前的页面,不会向 history 栈添加一个新的记录
this.$router.push('/login'):跳转到指定路由
27.路由守卫包括哪些
全局路由守卫:
(1)router.beforeEach(to,form,next) 全局前置守卫 进入路由之前
to:去往哪个页面 form:从哪个页面离开 next:必填否则页面空白,决定是否展示页面,去往to指向的页面
(2)router.afterEach(to,form) 全局后置守卫 进入路由之后
可在该阶段取消一些功能
组件路由守卫:
(1)beforeRouteEnter(to,form,next) 进入组件前
(2)beforeRouteUpdate(to,form,next) 组件更新时:路由复用同一个组件时
(3)beforeRouteUpdate(to,form,next) 离开当前路由时
路由独享守卫:
只针对一个页面使用,进入路由时触发,参数改变时不会触发
28.跨域
违反同源策略的就是跨域(同域名、同协议、同端口号)
(1)jsonp:利用script标签没有跨域限制,发送get请求,服务器会将值返回到callback函数中,再通过json.stringfy获取值
(2)Proxy:Proxy就是在客户端和服务端到建立一个中间商,在本地vue.config.js中的target配置需要代理的域名
29.http与https的区别
http协议是以明文方式发送内容,不提供数据加密,无状态的,不适用来传输敏感信息,端口号为80
https是具有安全性SSL加密传输协议,https由SSL+http协议构成的可进行加密传输、身份认证的网络协议,端口号为443