为了顺利通过面试,固需要强化理论。为了减轻P10阶段压力,固精选60题!
五、vue2/vue3⾯试题 (30T)
5.1 vue响应式原理
v2:采用数据劫持结合“发布-订阅”模式的方式,通过Object.defineProperty的 set 和 get,在数据变动时发布消息给订阅者触发监听。
v3:proxy配合Reflect来实现的,使用Proxy来进行数据的代理,通过Reflect反射来实现动态的数据响应式
5.2 vue组件通信
1.⽗传⼦ 在⼦组件的标签上定义属性 ⼦组件通过props来进⾏接受
2.⼦传⽗ ⼦组件通过this.$emit("⾃定义的事件",要传给⽗组件的数据), ⽗组件通过⼦组件的标签监听⾃定义的事件,通过⽅法来接收传递的数据
3.⾮⽗⼦组件通信 通过中央事件总线
4.vuex pinia
5.v-model
6.本地存储
7.ref和refs
8..sync 修饰符
9.$parent和$children
10.provide 和 inject
5.3 vue⽣命周期
实例的生命周期函数(官方11个):
创建阶段的四个:
beforeCreate:实例创建之前。
created:实例创建之后。
beforeMount:组件挂载之前。
mounted:组件挂载之后。
运行阶段的两个:
beforeUpdate:数据改变,视图更新之前。
updated:试图更新之后。
销毁阶段的两个:
beforeDestroy:实例销毁之前。
destroyed:实例销毁之后。
其他三个:
activated 被 keep-alive 缓存的组件激活时调用。
deactivated 被 keep-alive 缓存的组件停用时调用。
errorCaptured 2.5.0+ 新增当捕获一个来自子孙组件的错误时被调用
5.4 vue路由模式
vue的路由模式一共有两种,分别是哈希和history(历史).
hash 就是指 url 尾巴后的#号以及后面的字符,history没有带#,外观上比hash 模式好看些.
hash模式不会重新加载页面,主要原理就是onhashchange()事件;而history模式,如果前端的url和后端发起请求的url不一致的话,会报404错误,所以使用history模块的话我们需要和后端进行配合.
5.5 vue计算属性和监听器
1.computed是计算属性;watch是监听,监听data中的数据变化。
2.computed支持缓存,只有当其依赖的属性的值发生变化时,才会重新计算;watch不支持缓存,当对应属性发生变化的时候,响应执行。
3.computed不支持异步,有异步操作时无法监听数据变化;watch支持异步操作。
4.computed第一次加载时就监听;watch默认第一次加载时不监听(immediate: true)
5.computed中的函数必须调用return;watch不是。
使用场景:
- computed:一个属性受到多个属性影响,如:购物车商品结算。
- watch:一个数据影响多条数据,如:搜索数据。
- 数据变化响应,执行异步操作,或高性能消耗的操作,watch为最佳选择
5.7 vue中如何封装⾃定义组件
1.在components中创建vue文件,编写业务代码
2.使用props接收父组件传递的数据,使用emit向父组件发送数据
3.在父组件中导入、注册以后即可使用
5.8 vue3和vue2数据代理区别 (可参考5.1 vue响应式原理)
1.Vue3:使⽤了 Proxy 对象和reflect反射(操作对象数据)实现数据响应式,Proxy⽀持13种拦截操作。它可以代理整个对象不需要循环递归处理代理的数据,性能更好,不存在vue2中的bug问题。
2.Vue2:基于 Object.defineProperty 实现的。⼀次只能对⼀个属性进⾏监听,需要遍历来对所有属性监听。在遇到⼀个对象的属性还是⼀个对象的情况下,需要递归监听。
5.9 vue内置常⽤指令?
v-if:根据条件渲染元素,当条件为真时,元素被渲染,否则不渲染。
v-show:根据条件显示或隐藏元素,当条件为真时,元素显示,否则隐藏。
v-for:循环渲染元素,可以遍历数组、对象、字符串等。
v-bind:绑定元素属性或组件属性,可以动态地将数据绑定到元素或组件上。
v-on:绑定事件监听器,可以在元素上监听各种事件。
v-model:双向绑定表单元素和数据,可以在表单元素上实现数据的双向绑定。
v-text:将数据绑定到元素的⽂本内容中,可以实现数据的单向绑定。
v-html:将数据绑定到元素的HTML内容中,可以实现HTML的渲染。
v-pre:跳过元素和⼦元素的编译过程,可以⽤来优化性能。
v-cloak:在元素加载完成之前隐藏元素,可以防⽌元素在渲染之前显示出原始状态
5.10 vue常⽤修饰符?
.stop:阻⽌事件冒泡。
.prevent:阻⽌默认事件。
.capture:添加事件侦听器时使⽤事件捕获模式。
.self:只当事件在该元素本身(⽽不是⼦元素)触发时触发回调。
.once:事件只触发⼀次。
.native:监听组件根元素的原⽣事件。
.sync:双向绑定,⼦组件可以修改⽗组件的数据。
.lazy:只有在“change”事件触发时才更新。
.number:输⼊值⾃动转为数字类型。
.trim:输⼊值⾃动去除⾸尾空格。
5.11 vue虚拟dom?
虚拟dom 是根据模板生成一个js对象,根据这个js对象再去生成真实的dom,对复杂的文档DOM结构,提供一种方便的工具,进行最小化的DOM操作(使用createElement方法)
5.12 vue-diff 算法?
当data发生改变会根据新的数据生成一个新的虚拟dom ,新的虚拟dom和旧的虚拟dom进行对比,这个对比的过程就是diff算法,会找到不同地方,只去渲染不同的地方
5.13 keep-alive应⽤场景
keep-alive是vue内置的一个组件,其作用就是缓存不活动的组件。keep-alive可以使被包含的路由组件状态维持不变,即便是组件切换了,其内的状态依旧维持在内存之中。在下一次显示时,也不会重新渲染。
include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max-数字最多可以缓存多少组件。
5.14 vue有哪些内置组件?
component 动态组件
transition 动画
transition-group 动画
keep - alive 缓存
slot 插槽
5.15 vue-slot插槽
插槽就是一个占位符,将自定义组件的内容展示出来.
● 默认插槽:又名匿名插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插槽。
● 具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。
● 作用域插槽:可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。
5.16 前端项⽬跨域?
1.1前端⽅式:
-JSONP:通过动态创建 script 标签,来实现跨域请求数据,利⽤script标签没有跨域限制的特性,但只⽀持 GET 请求。
-proxy代理:通过在同域名下设置代理服务器,将跨域请求转发到⽬标服务器,再将响应结果返回给浏览器,但需要额外的服务器开销。
1.2后端⽅式:
-CORS:在服务端设置响应头,允许跨域请求,需要浏览器⽀持,兼容性较好。
-nginx 反向代理:通过在 nginx 服务器上设置反向代理,将跨域请求转发到⽬标服务器,再将响应结果返回给浏览器,但需要额外的服务器开销。
5.18 vue路由传参⽅式?
params传参 可以通过this.$route.params获取参数
query传参 可以通过this.$route.query获取参数
5.19 Vue事件穿透的⽅法?
.native 事件穿透,让我们可以在⾃定义组件上定义事件和⽅法
<son @click.native ="two"></son>
5.20 vue是怎么操作dom节点的?
1.javascript原生DOM操作 document.getElementById("btn");
2.vue ⾃带的 ref 属性
5.21 说说对vuex的理解?
vuex是一个状态管理⼯具,通过vuex可以实现组件之间数据共享的问题.
1、state - 存放数据 存放store实例的状态对象,用于定义共享的数据。
2、action - 异步操作 向store发出调用通知,执行异步操作
3、mutations - 同步操作 用来修改state 修改器,它只用于修改state中定义的状态变量。
4、getters - 计算属性,外部程序通过它获取变量的具体值,或者在取值前做一些计算
5、module- 模块化 对state进行分类处理
5.22 vue中key的作⽤是什么?
保证虚拟DOM在其同级元素中具有唯一性。在 Diff 算法中会借助元素的 key值来判断该元素是新创建的还是被需改的,从而减少不必要的重复渲染。key应具有唯一性,不推荐使用索引。
5.23 vue中data发⽣变化,视图不更新如何解决?
由于 JavaScript的限制,Vue⽆法检测到属性的新增或删除。⼀般通过this.$set⽅法解决. 它有三个参数,分别是⽬前对象,新增属性,新增的值
5.24 为什么vue中data必须是⼀个函数?
如果data是⼀个函数的话,这样每复⽤⼀次组件,就会返回⼀份新的data,类似于给每个组件实例创建⼀个私有的数据空间,让各个组件实例维护各自的数据,避免相互影响。
5.25 $nextTick⽅法有什么作⽤?
$nextTick也叫做异步更新队列⽅法,主要作⽤就是等待dom元素加载完毕之后才会执⾏的回调函数,我们经常会在$nextTick⽅法⾥⾯获取dom元素
5.27 vue路由守卫?
vue路由守卫就是进入⻚⾯时触发的钩⼦函数
第一种全局路由守卫,beforeEach 前置守卫,beforeResolve 解析守卫,afterEach 后置守卫
第二种组件内路由守卫,beforeRouteEnter 进⼊之前,beforeRouteUpdate 更新之前,beforeRouteLeave 离开之前
第三种路由独享守卫,beforEnter 路由进⼊之前
5.28. v-if与v-show的区别?
v-if和v-show都是控制元素的显示与隐藏,
v-if会创建或删除对应的dom元素,而v-show则是通过display来控制元素的显示与隐藏.
v-if比较耗费性能,所以涉及到频繁的显示/隐藏操作建议使用v-show,如果不是频繁操作的话,我们可以v-if
5.29. v-for与v-if的优先级那个⾼?如果同时使⽤v-for和v-if怎么解决?
vue2中:v-for的优先级⾼. 因为v-for的时候我们才开始渲染dom元素,这个v-if还⽆法进⾏判断.v-for和v-if不能同时使⽤,我们可以通过div或者template标签来进⾏包裹,把v-if写到包裹的标签上⾯(写到v-for外⾯)
vue3中:情况相反
5.30. 你都做过哪些 Vue 的性能优化?
1.单⻚⾯采⽤keep-alive缓存组件。
2.尽可能拆分组件,来提⾼复⽤性、增加代码的可维护性。
3. key 保证唯⼀性,不要使⽤索引
4.合理使⽤路由懒加载、异步组件。
5.图⽚懒加载
6.路由懒加载
7.cdn加速
8.服务端 gzip 压缩
5.31. Vue2.0和3.0区别? (P9 day01)
1.选项api改为组合api
2.v-if 和v-for优先级不⼀样了,vue2是v-for优先级更⾼,vue3是v-if优先级更⾼
3.插槽不⼀样了,vue2中可以直接使⽤slot,vue3 必须使⽤v-slot
4.vue3没有过滤器了
5.模板根节点,vue3可以有多个根节点
5.35. Vue3为何⽐Vue2快 (P9 day01)
1.proxy响应式:深度监听,性能更好(获取到哪⼀层才触发响应式get,不是⼀次性递归)
2.PatchFlag 动态节点做标志
3.HoistStatic 将静态节点的定义,提升到⽗作⽤域,缓存起来。多个相邻的静态节点,会被合并起来
4.CacheHandler 事件缓存
5.SSR优化: 静态节点不⾛vdom逻辑,直接输出字符串,动态节点才⾛
6.Tree-shaking 根据模板的内容动态import不同的内容,不需要就不import
5.36. v-model双向绑定原理
v-model 可以看成是:value + @input⽅法的语法糖,在内部为不同的输⼊元素使⽤不同的属性并抛出不同的事件
⼆、TypeScript⾯试题(15T)
2.1 TypeScript的主要特点是什么?
TypeScript 是 JavaScript 的类型的超集,⽀持 ES6 语法,⽀持⾯向对象编程的概念,如类、
接⼝、继承、泛型等
跨平台:TypeScript 编译器可以安装在任何操作系统上,包括 Windows、macOS 和 Linux。
ES6 特性:TypeScript 包含计划中的 ECMAScript 2015 (ES6) 的⼤部分特性,例如箭头函数。
⾯向对象的语⾔:TypeScript 提供有标准的 OOP 功能,如类、接⼝和模块。
静态类型检查:TypeScript 使⽤静态类型并帮助在编译时进⾏类型检查。因此,你可以在编写代码时发现编译时错误,⽽⽆需运⾏脚本。
可选的静态类型:如果你习惯了 JavaScript 的动态类型,TypeScript 还允许可选的静态类型。
2.2 TypeScript和JavaScript的区别是什么?
Typescript 是 JavaScript 的超集,可以被编译成 JavaScript 代码。⽤ JavaScript 编写的代码,在TypeScript 中依然有效。
Typescript 是纯⾯向对象的编程语⾔,包含类和接⼝的概念。 程序员可以⽤它来编写⾯向对象的服务端或客户端程序,并将它们编译成 JavaScript 代码
2.3 TypeScript⽀持的访问修饰符有哪些?
公共(public),类的所有成员,其⼦类以及该类的实例都可以访问。
受保护(protected),该类及其⼦类的所有成员都可以访问它们。 但是该类的实例⽆法访问。
私有(private),只有类的成员可以访问它们。
如果未指定访问修饰符,则它是隐式公共的,因为它符合 JavaScript 的便利性。
2.4 解释⼀下TypeScript中的枚举?
枚举是TypeScipt数据类型,它允许我们定义⼀组命名常量。 使⽤枚举去创建⼀组不同的案例变得更加容易。它是相关值的集合,可以是数字值或字符串值。
2.5 TypeScript中const和readonly的区别是什么?
const⽤于变量,readonly⽤于属性
const在运⾏时检查,readonly在编译时检查
使⽤const变量保存的数组,可以使⽤push、pop等⽅法。但是如果使⽤Readonly 声明的数组不能使⽤push、pop等⽅法
2.6 TypeScript中never和void的区别?
void 表示没有任何类型(可以被赋值为 null 和 undefined)。
never 表示⼀个不包含值的类型,即表示永远不存在的值。
拥有 void 返回值类型的函数能正常运⾏。拥有 never 返回值类型的函数⽆法正常返回,⽆法终⽌,或会抛出异常。
2.7 TypeScript中的类型断⾔是什么?
类型断⾔可以⽤来⼿动指定⼀个值具体的类型,即允许变量从⼀种类型更改为另⼀种类型。类型断⾔的关键字为as
当你⽐ TS 更了解某个值的类型,并且需要指定更具体的类型时,我们可以使⽤类型断⾔。
2.9 使⽤TS实现⼀个判断传⼊参数是否是数组类型的⽅法?
2.11 TS中的泛型是什么?
泛型是提供创建可重⽤组件的⽅法的⼯具。 它能够创建可以使⽤多种数据类型⽽不是单⼀数据类型的组件。 ⽽且,它在不影响性能或⽣产率的情况下提供了类型安全性。 泛型允许我们创建泛型类,泛型函数,泛型⽅法和泛型接⼝。
2.12 TS中什么是⽅法重载?
重载是指通过为同一个函数提供多个函数类型定义来实现多种功能的目的。这些方法的名字必须相同,而参数不同,返回类型可以相同也可以不同
2.13 TS中的类是什么,如何定义?
类表示⼀组相关对象的共享⾏为和属性。
2.14 如何在TS中实现继承?
继承是⼀种从另⼀个类获取⼀个类的属性和⾏为的机制。它是⾯向对象编程的⼀个重要⽅⾯,并且具有从现有类创建新类的能⼒。
继承可以通过使⽤extend关键字来实现。
2.15 说说TS中的类及其特性?
TypeScript 引⼊了类,以便它们可以利⽤诸如封装和抽象之类的⾯向对象技术的好处。
TypeScript 编译器将 TypeScript 中的类编译为普通的 JavaScript 函数,以跨平台和浏览器⼯作。
⼀个类包括以下内容:
构造器(Constructor)
属性(Properties)
⽅法(Methods)
类的其他特性有:
继承(Inheritance)
封装(Encapsulation)
多态(Polymorphism)
抽象(Abstraction)
2.16 TS中的类型有哪些?
内置:包括数字(number),字符串(string),布尔值(boolean),⽆效(void),空值(null)和未定义(undefined)。
⽤户定义的:它包括枚举(enums),类(classes),接⼝(interfaces),数组(arrays)和元组(tuple)。
2.17 TS中的interface和type有什么区别?
type 可以声明基本类型别名,联合类型,元组等类型;interface不可以
type 语句中还可以使⽤ typeof 获取实例的类型进⾏赋值;interface不可以
interface 能够合并多个同名声明;type 重名会报异常
四、JavaScript⾯试题 (15T)
4.1 Js有哪些数据类型?
基本数据类型: Undefined、Null、Boolean、Number、String、Symbol、BigInt。
引⽤数据类型:object,function,array
4.2 数据类型检测的⽅式有哪些?
4.4 谈谈你对作⽤域和作⽤域链的理解
作⽤域规定了变量能够被访问的范围,离开了这个范围变量便不能被访问;
嵌套关系的作⽤域串联起来形成了作⽤域链
变量的查找机制
函数被执⾏时,会优先查找当前函数作⽤域中的变量;如果当前作⽤域中查找不到会逐级向上查找⽗级作⽤域,直到全局作⽤域
4.6 如何改变this指向
js中允许改变函数中this的指向,有3个⽅法可以动态指定普通函数中this的指向
- call => fun.call(this,arg1,arg2....)
- apply => fun.apply(this,[arg1,arg2....])
- bind()⽅法不会调⽤函数,fun.bind(this,arg1,arg2,...)
4.7 for...in和for...of的区别
for...in 循环主要是为了遍历对象⽽⽣,不适⽤于遍历数组;for...of 循环可以⽤来遍历数组、类数组对象,字符串、Set、Map 以及 Generator 对象。
4.8 forEach和map⽅法有什么区别?
这⽅法都是⽤来遍历数组的,两者区别如下:
forEach()⽅法会针对每⼀个元素执⾏提供的函数,如果遍历的元素是引⽤数据类型,则可以改变指针指向的堆内存⾥的值,该⽅法没有返回值;
map()⽅法返回⼀个新数组,新数组中的值为原数组调⽤函数处理之后的值,如果遍历的元素是引⽤数据类型,则可以改变指针指向的堆内存⾥的值
4.9 什么是深拷⻉,浅拷⻉以及如何实现
浅拷⻉指的是创建新的数据,这个数据有着原始数据属性值的⼀份精确拷⻉;如果属性是基本类型,拷⻉的就是基本类型的值。如果属性是引⽤类型,拷⻉的就是内存地址。
常⻅的浅拷⻉:Object.assign、Object.create、slice、concat()、展开运算符
深拷⻉开辟⼀个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改⼀个对象的属性,不会改变另⼀个对象的属性
常⻅的深拷⻉⽅式有: _.cloneDeep()、jQuery.extend() 、JSON.stringify()、⼿写循环递归
4.16 原型链
proto属性链状结构称为原型链
原型链为对象成员的查找机制提供了⼀个⽅向,或者是⼀条路线
4.19 继承有哪些
盗⽤构造函数、原型继承 、组合继承 原型式继承、寄⽣式继承、寄⽣式组合继承
4.21 async/await是什么?
async/await 是 ES2017 中引入的,用于处理异步操作的语法糖,使得异步代码看起来更像是同步代码,这样可以让我们更容易理解和编写。
4.23 什么是防抖节流
防抖:单位时间内,频繁触发事件,只执⾏最后⼀次
使⽤场景:输入框输入时,只需⽤户最后⼀次输⼊的用户名是否可用
节流:单位时间内,频繁触发事件,只执⾏⼀次(前⼀个任务还在,取消触发)
使⽤场景:⿏标移动,⻚⾯尺⼨缩放,滚动条滚动
4.24 什么是Event Loop
Event Loop 即事件循环,是指浏览器或 Node 的一种解决 javaScript 单线程运行时不会阻塞的一种机制,也就是我们经常使用 异步 的原理。
4.26 什么是事件捕获(Event Capturing)
4.27 什么是事件委托
4.29 什么是闭包以及作⽤
- 2023新版全栈跨校区面试题库汇编 https://kdocs.cn/l/cn4l1Id50iJG
- P7-vue实战题库(理论+面试) https://kdocs.cn/l/ckeSTJNC4F9C
- P6vue基础-理论+面试题-带答案版 https://kdocs.cn/l/coSh1i9ElkK1