2020面试汇总
0729
1、为啥从上家公司离职?
答:因人而异。
2、js基本数据类型有哪些?
答:五种基本数据类型--string、number、null、undefined、Boolean
一种复杂数据类型--Object
3、vue 计算属性和监听属性区别?
答:计算属性computed,自动监听依赖值的变化,动态返回内容;
可以关联多个实时计算的对象,当这些对象中的其中一个改变时都会触发这个属性;具有缓存能力,所以只有当数据再次改变时才会重新渲染,否则就会直接拿取缓存中的数据。
监听属性watch,一个过程,在监听值变化时,可以触发回调。
watch用于观察和监听页面上的vue实例,当你需要在数据变化响应时,执行异步操作,或高性能消耗的操作,那么watch为最佳选择
区别:用法上,只是需要动态值,那就用计算属性;需要知道值的改变后执行业务逻辑,才用 watch。
4、举例子说明watch监听实际应用场景
答:1)监听路由变化
例:watch: {
5、watch 里面 deep 属性原理
答:对象和数组都是引用类型,引用类型变量存的是地址,地址没有变,所以不会触发watch。这时我们需要进行深度监听,就需要加上一个属性 deep,值为 true
注意:只要对象的属性发生变化,就会执行handler函数;如果将监听对象中的具体属性,则可以通过计算属性computed作为中间层进行监听
使用immediate:true,会在初始化watch时就立即执行handler回调函数,而不用等下一次数据更新。
使用deep:true,才会递归监听对象的属性(如果监听的是对象或数组)。
deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler
优化,我们可以是使用字符串形式监听。
6、除了watch监听路由变化,还有什么方法可以监听到?
https://www.cnblogs.com/crazycode2/p/8727410.html
答:可以使用路由守卫钩子函数监听路由变化。
(拓展)路由守卫函数有哪些?
https://www.cnblogs.com/dengyao-blogs/p/11576614.html
答:1)概念:路由守卫有点类似于ajax的请求拦截器,就是请求发送之前先给你拦截住做一些事情之后再去发送请求,同样这里的路由守卫意思差不多;简单理解为就是你在进路由之前,首先把你拦住,对你进行检查。
2)vue-router钩子函数分三大类:
a、全局钩子函数:[ main.js里面 ]
-- beforeEach(to,from,next):一般用于控制权限;例如:登录页、用户达到什么级别跳页面...
-- afterEach(to,from):一般用来重置页面滚动条位置
b、路由独享钩子函数: [ 路由配置文件,单个路由配置 ]
-- beforeEnter(to,from,next):只能设置改变前的钩子,不能设置改变后的钩子
c、组件内钩子函数:[ 组件内export default{} ]
-- beforeRouterEnter(to,from,next):路由进入前调用,vue实例还没创建,不存在this
-- beforeRouterUpdate(to,from,next):路由修改时调用,可以访问实例
-- beforeRouterLeave(to,from,next):路由离开时调用,可以访问实例
7、实际项目中遇到问题怎么解决?
答:1)技术问题,如果能用插件解决,优先插件解决;
2)业务逻辑上的问题,多找产品交流沟通,透彻了解需求;
3)也可以尝试找同事一起讨论如何实现。
8、fetch、axios有什么区别?
https://www.jianshu.com/p/8bc48f8fde75
答:传统 Ajax 指的是 XMLHttpRequest(XHR), 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。
-- JQuery ajax 是对原生XHR的封装,除此以外还增添了对JSONP的支持。经过多年的更新维护,真的已经是非常的方便了,优点无需多言;如果是硬要举出几个缺点,那可能只有:
** 本身是针对MVC的编程,不符合现在前端MVVM的浪潮
** 基于原生的XHR开发,XHR本身的架构不清晰
** JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
** 不符合关注分离(Separation of Concerns)的原则
** 配置和调用方式非常混乱,而且基于事件的异步模型不友好
-- axios Vue2.0之后,尤雨溪推荐大家用axios替换JQuery ajax;axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。
** 从浏览器中创建 XMLHttpRequest
** 支持 Promise API
** 客户端支持防止CSRF
** 提供了一些并发请求的接口(重要,方便了很多的操作)
** 从 node.js 创建 http 请求
-- fetch 号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
** 基于标准 Promise 实现,支持 async/await
** 更加底层,提供的API丰富(request, response)
** 脱离了XHR,是ES规范里新的实现方式
** 只对网络请求报错,对400,500都当做成功的请求
** 默认不会带cookie,需要添加配置项
** 没有办法原生监测请求的进度,而XHR可以
9、es6新特性接触过哪些?你是怎么学习es6的?
https://www.jianshu.com/p/ac1787f6c50f
https://blog.csdn.net/qq_45534098/article/details/107787529
答:1)es6新特性
-- let和const:let不会声明提升,const定义时必须被赋值
-- 模板字符串 `` :基本字符串格式化,表达式直接使用${}嵌入
-- 数组新增了map和reduce方法
** map(func):接收一个函数,将数组里面的元素处理后,返回一个新数组
** reduce(func,val-可选):从左到右数组中的元素用reduce处理,并把处理的结果作为下次reduce的第一个参数。如果是第一次,会把前两个元素作为计算参数,或者把用户指定的初始值作为起始参数。
-- 扩展运算符(...):...arr将一个数组分隔成由逗号分隔的参数序列
-- 箭头函数:this只想上下文里对象的指向,没有上下文对象,指向windows;call、apply、bind等方法不能改变this指向
-- 解构赋值:字符串、对象、数组
-- promise:异步操作
-- map:本质是与Object类似的结构。不同在于,Object强制规定key只能是字符串。而Map结构的key可以是任意对象(object 是 <string,object>集合,map是 <object,object>集合)
** map .set(key, value) // 添加
** map.clear() // 清空
** map.delete(key) // 删除指定元素
** map.has(key) // 判断是否存在
-- set:本质与数组类似。不同在于Set中只能保存不同元素,如果元素相同会被忽略。(最简单的数组去重方法)
** set.add(1) // 添加
** set.clear() // 清空
** set.delete(2) // 删除指定元素
** set.has(2) // 判断是否存在
** set.forEach(function(){}) //遍历元素
2)阮一峰教程
10、解构赋值可以解构字符串吗?
答:可以。字符串在解构赋值的时候被转换成一个类似数组的对象,数组存在length属性,所以还可以对这个属性进行解构赋值。
11、props是单向数据流还是双向数据流?怎么修改props的值
答:官方解释:props是单向数据流,父级的prop更新会向下流向子组件,但反过来是不行的。这样做是防止子组件意外改变父组件的值,从而导致数据流向难以理解。
修改props的值:
-- 在子组件内定义一个data property,并将这个prop作为初始值
-- 使用prop值定义一个计算属性
-- 父组件中此Prop用data替换,并且在watch中监听变化,在子组件中通过$refs取到,此时可以向父组件写入(可以根据子组件此属性变化的需求选择是否在子组件监听),避开了关于Prop的规定,实现了双向绑定。
总结:
1)如果传递的prop是基本数据类型,子组件不能修改父组件的值,符合单向数据流
2)如果是引用数据类型,父子组件是可以双向通信的,违背了单向数据流
故:props传递参数的不同,决定子组件是否能改变父组件prop传递的值。
12、props可以定义多种类型吗?
答:可以。
例:-- 基本类型 propsA:Number -- 多种数据类型 propsB:[String,Number]
-- 必填的字符串 propC: { type: String, required: true } -- 带有默认值的数字 propD: { type: Number, default: 100 }
13、v-for 做循环的时候为什么要带上key?
答:v-for渲染元素列表时,使用就地复用策略;列表数据修改的时候,它会根据key值去判断某个值是否变化,如果被修改,就重新渲染这一项,反之就复用之前的元素。key的作用是为了更高效的更新虚拟dom。
简单来说,vue在进行页面更新时,会通过Diff算法对虚拟DOM进行更新,因为真实的DOM消耗比较大。
(拓展)diff算法
答:diff算法--用来计算出虚拟dom(Virtual Dom)被改变的部分,然后针对该部分进行原生dom操作,从而避免渲染整个页面。
diff算法三大策略(顺序执行):
-- tree diff:对树每一层进行遍历,找出不同
-- component diff:数据层面比较差异(同一类型组件,继续原策略执行;不是同一类型组件,替换所有子节点)
-- element diff:真实dom渲染,结构差异比较
14、vue-cli脚手架用什么版本?
答:vue目前用的是v2.6.11(简称v2.0)。
vuecli用的是3.0版本,目前固定版本就是3.0。
vue框架版本调整,脚手架肯定会调整;但是脚手架更新并不会意味着vue更新。
(拓展)vue和vuecli区别?
答:vue是框架,vuecli是由vue框架衍生出的脚手架,是一套大众化的前端自动化解决方案,核心是 webpack,还有相关辅助插件组成,前端自动化规则,输入输出文件格式,文件的监听,文件的路径都是已经配置好了。
实际开发中按照需求做调整。
也可以自己按照vue框架自己搭建,但是需要丰富的经验,否则可能忽略很多细节。
15、你对webpack了解多少?
https://www.cnblogs.com/gaoht/p/11310365.html
https://www.cnblogs.com/chengxs/p/11022842.html
答:...
16、你知道arguments嘛?作用?
https://www.jianshu.com/p/e6bfa4bdf718
答:它是js的内置对象,每个函数都具有一个arguments对象,它包含了函数所调用的参数,通常把它当做数组来用,用它的length得到参数数量,但它实际却不是数组,不可调用数组的方法。
(拓展)可以把argument转换成真正的数组嘛?
答:可以的。
-- var args = Array.prototype.slice.call(arguments)
args是一个标准数组,可以使用数组的方法了。