前言
经过这段时间的面试,在刷面试题时发现面试题类的文章要么就是一些简单的回答,要么就是长篇大论;为了方便大家,也为了方便自己,从而写出了这篇文章。
此篇文章通过站在面试官的角度来问你问题,答案分为两个部分普通版
、深入版
普通版:用于面试时回答
深入版:都是引用的链接,用于深入学习
最好看深入版链接的文章进行学习,这样有自己的理解,也更好在面试的时候作答
文章灵感来源于HearLing大佬的文章:化身面试官出 30+Vue 面试题,超级干货(附答案)|牛气冲天新年征文
在此感谢大佬
------ 废话不多说,咋们开始 ------
你先做个自我介绍吧 。。。 在你自我介绍的时候呢,我就看看你做过的项目,技术栈什么的。
先来个简单点的,顺便想下接下来该问那些技术栈
HTML/CSS 篇
垂直水平居中有哪些方法
答案
普通版
position
:负margin
position: absolute; // 负margin top: 50%; left: 50%; margin-top: -高度的一半; margin-left: -宽度的一半; // calc,与上同理 top: calc(50% - 50px); left: calc(50% - 50px); // transform transform: translate(-50%, -50%);
flex
布局:justify-content: center; align-items: center;
不错,不错,问下能否能熟练的运用
未知宽度和高度图片,在一个 200px*200px 的 DIV 里面,需要水平垂直居中自适应显示
答案
.imgDiv {
width: 200px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
.imgDiv img {
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}
emmmmm,看来蛮熟练的,来个难点的
浏览器的回流与重绘知道吗?知道的话说一下
答案
普通版
- 回流 (Reflow):当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
- 重绘 (Repaint):当页面中元素样式的改变并不影响它在文档流中的位置时,浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
- 一句话:回流必将引起重绘,重绘不一定会引起回流。
- 性能影响:回流比重绘的代价要更高;有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。
在回答的时候最好加上如何避免,如果回答的时候没有回答如何避免,那么面试官可能会问如何避免
看到简历上面有ES6的技术栈,问一下
ES6/ES7 篇
ES6 的新特性有了解吗?用到了那些?
答案
普通版
let
和const
- 箭头函数、展开运算符
...
- 类
class
Symbol
Promise
、async/await
Set
和Map
- 数组的扩展
好家伙,说了这么多,有的问了
你刚才说到了 Let、const,那么他们什么区别呢?又和 var 有什么区别呢?
答案
普通版
var
:存在变量提升,可以重复声明,全局变量属于顶层对象let、cosnt
:不存在变量提升,不可以重复声明,块级作用域let
可以修改值;const
不能修改值(引用类型仅保证地址不被修改)- 在代码块内,使用let、const命令声明变量之前,该变量都是不可用的
- 面试中,面试官可能会接着问你暂时性死区
这都难不倒你,问下你Promise这方面的,看你如何回答
Promise、async/await 说一说
答案
普通版
Promise
:有等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected),一旦promise
被resolved
或rejected
,不能再迁移至其他任何状态。有Promise.all
和Promise.race
两个方法Promise.all
:接收一个promise
数组。当数组中所有的promise
的状态都达到resolved
的时候,Promise.all
的状态就会变成resolved
,如果任意一个状态变成了rejected
,那么状态就会变成rejected
,可以解决并行的问题。Promise.race
:接收一个promise
数组。,哪个先执行完,race
就直接执行完,并从then
中取值。async
:是Generator
函数的语法糖,用于申明一个function
是异步的,返回的是一个promise
对象await
:是一个表达式,这个表达式的计算结果是promise
对象或者其它值,如果等待的是promise
对象,它会阻塞后面的代码,等着promise
对象resolve
,然后得到resolve
的值,作为表达式的运算结果。
- 面试中,面试官可能会接着问你Promise的值穿透
- 这里建议大伙尝试手写实现Promise
说的挺详细的,看来有点功底呀,继续
使用箭头函数应注意什么?
答案
普通版
- 用了箭头函数,
this
就不是指向window
,而是父级(指向是可变的) - 不能够使用
arguments
对象 - 不能用作构造函数,这就是说不能够使用
new
命令,否则会抛出一个错误 - 不可以使用
yield
命令,因此箭头函数不能用作Generator
函数
ForEach 和 Map 有什么区别,是否会改变原数组
答案
普通版
forEach
方法不会返回执行结果, 而是undefined
map
方法会得到一个新的数组并返回- 如果值是引用类型的话就会改变
class 说一说
答案
普通版
class
是一个语法糖,其底层还是通过 构造函数 去创建的。所以它的绝大部分功能,ES5都可以做到。新的class
写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。class
可以通过extends
关键字实现继承super
:有两种用法,一种是super
方法,super
方法只能出现在constructor
方法中;另外一种是super
对象,一般出现在子类覆盖父类的方法中。
可以呀,看来ES6方面是难不倒你了;看看其余的咋样
JavaScript 篇
JS 执行机制知道吗?说一下
答案
普通版
- js代码分为同步任务和异步任务
- 同步任务会进入主线程,异步任务会进入Event Table(事件表),当事件表中的异步任务完成后会在Event Queue(事件队列)中注册回调函数
- 主线程任务全部完成后,才会完成Event Queue中的任务
- js解析器会不断地重复检查主线程执行栈是否为空,然后重复第3步,这就是Event Loop(事件循环)
- 异步任务之宏任务:宏任务有
script
、setTimeout
、setInterval
、I/O 操作
- 异步任务之微任务:宏任务一般为
ajax
、Promise.then
、process.nextTick
等 Event Loop
:
- 1、整体
script
作为第一个宏任务进入主线程 - 2、遇到的宏任添加进宏任务列表
- 3、遇到的微任务添加进微任务列表
- 4、执行完之后,取出微任务队列中的所有任务依次执行
- 5、如果微任务执行过程中产生了新的微任务,则继续执行微任务,直到微任务的队列为空
- 6、循环,循环以上 1 - 5
- 1、整体
new 一个函数发生了什么
答案
普通版
- 创造一个全新的对象
- 链接到原型:
obj.__proto__ = Con.prototype
- 绑定
this
- 返回新对象(如果构造函数有自己
retrun
时,则返回该值)
this 说一说呗
答案
普通版
- 在函数中,可以引用运行环境中的变量。因此就需要一个机制来让我们可以在函数体内部获取当前的运行环境,这便是
this
;它是一个对象,产生与函数有关,与执行环境绑定 this
绑定规则:默认绑定、隐式绑定、硬绑定、new绑定
- 默认绑定:在不能应用其它绑定规则时使用的默认规则,通常是独立函数调用
- 隐式绑定:函数的调用是在某个对象上触发的,即调用位置上存在上下文对象。典型的形式为 XXX.fun()
- 硬绑定:通过call,apply,bind的方式,显式的指定this所指向的对象
- new绑定:看
new
一个函数发生了什么
闭包说一说
答案
普通版
- 闭包是 JS 函数作用域的副产品,闭包可以让一个函数访问并操作其声明时的作用域中的变量和函数,并且,即使声明时的作用域消失了,也可以调用
- 《JavaScript高级程序设计》:闭包是指有权访问另一个函数作用域中的变量的函数
- 《JavaScript权威指南》:从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
- 《你不知道的JavaScript》:当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
- 使用闭包会让函数中的变量保存在内存中,如果滥用闭包会造成性能影响,如果在IE中会导致内存泄露
call、apply、bind 说一说吧
答案
普通版
- 它们都是用于改变
this
的指向 - 共同点:三个方法的第一个参数,都是this。如果使用的时候不关心
this
是谁的话,可以直接设置为null
call
与apply
的区别:
- 1、
apply
是第2个参数,这个参数是一个数组:传给函数参数都写在数组中。 - 2、
call
从第2~n的参数都是传给fun的。
- 1、
call/apply
与bind
的区别:
- 1、
call/apply
改变了函数的this
上下文后,马上执行该函数,返回的是调用函数的返回值 - 2、
bind
改变了this
上下文后,返回改变了上下文后的函数,不执行该函数
- 1、
什么是防抖?什么是节流?
答案
普通版
- 防抖 (debounce):
- 理解说明:在函数多次频繁触发时,函数执行一次后,只有大于设定的执行周期后才会执行第二次
- 使用场景:页面滚动(
scroll
)、DOM
元素的拖拽(mousemove
)、抢购点击(click
)、播放事件算进度信息
- 节流 (throttle):
- 理解说明:在函数频繁触发是,在规定之间以内,只让最后一次生效
- 使用场景:搜索框实时联想(keyup/input)、按钮点击太快,多次请求(登录、发短信)、窗口调整(resize)
数组如何去重和扁平化
答案
普通版
- 数组去重:
- 1、ES6的
new Set()
配合from
或者 展开运算符...
- 2、利用
filter
配合indexOf
- 3、双循环去重
- 1、ES6的
- 扁平化:
- 1、递归
- 2、利用
toString
把数组变成以逗号分隔的字符串,然后遍历数组把每一项再变回原来的类型 - 3、
flat(depth)
方法,默认值为1,不管多少层则可以用Infinity
关键字作为参数
深拷贝和浅拷贝区别和实现
答案
普通版
- 浅拷贝:重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会相互影响。
- 深拷贝:从堆内存中开辟一个新的区域存放新对象,对对象中的子对象进行递归拷贝,拷贝前后的两个对象互不影响。
- 浅拷贝实现:
- 1、
Object.assign()
- 2、展开运算符
...
- 3、数组的
concat()
- 4、数组的
slice()
- 1、
- 深拷贝实现:
1、利用
JSON.parse(JSON.stringify())
方法,但是不能识别undefined
、symbol
、function
;RegExp
引用类型会变成空对象,拷贝Date
引用类型会变成字符串2、递归实现
看来基础掌握得非常好,在问下VUE
VUE 篇
说下 VUE 的生命周期
答案
普通版
生命周期 |
发生了什么 |
---|---|
beforeCreate | 创建前。在当前阶段 data 、 methods 、 computed 、以及 watch 上的数据和方法都不能被访问
|
created | 创建后。当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发 updated 函数。可以做一些初始数据的获取,在当前阶段无法与 Dom 进行交互,如果非要想,可以通过 vm.$nextTick 来访问。推荐在在这个周期中调用异步请求 |
beforeMount | 挂载前。在这之前 template 模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发 updated |
mounted | 挂载后。在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs 属性对Dom进行操作 |
beforeUpdate | 更新前。也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染 |
updated | 更新后。当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新 |
beforeDestroy | 销毁前。在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器 |
destroyed | 销毁后。这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁 |
- 使用
keep-alive
会出现两个生命周期:activited
:组件被激活前deactivated
:组件被销毁时调用
- 组件生命周期调用顺序: 调用顺序都是先父后子,渲染完成的顺序是先子后父。
- 组件的销毁调用顺序: 先父后子,销毁完成的顺序是先子后父
说下 VUE 响应式数据/双向绑定原理
答案
普通版
- vue2.x :响核心就是
Object.defineProperty()
- 1、
initData
初始化用户传入的参数 - 2、
Observe
(观察者)观察props
与state
,遍历props
与state
,对每个属性创建独立的监听器(watcher
) - 3、使用
defineProperty
重写每个属性的setter/getter(defineReactive)
,getter
做依赖收集,setter
派发更新。整体来说是一个 数据劫持 + 发布-订阅者模式。
- 1、
- vue3.x : 改用
Proxy
和Reflect
替代Object.defineProperty()
可以原生监听数组,可以监听对象属性的添加和删除,不需要深度遍历监听
说下 VUE 路由模式
答案
普通版
- hash模式:响核心就是
Object.defineProperty()
- 1、 # 号后面
hash
值的变化,不会导致浏览器向服务器发出请求,浏览器不发出请求,就不会刷新页面 - 2、 通过监听 hashchange 事件可以知道
hash
发生了哪些变化,然后根据hash
变化来实现更新页面部分内容的操作
- 1、 # 号后面
- history 模式: history 模式的实现,主要是 HTML5 标准发布的两个
pushState
和replaceState
API,这两个 API 可以在改变 url时,不会发送请求。通过监听 url 变化来实现更新页面部分内容的操作 - 两者的区别:
- 1、hash 可以支持低版本浏览器和 IE
- 2、hash 模式有“#”,history 模式没有
说下 VUE 中的 v-if 和 v-show 的区别
答案
普通版
- v-for: 操作的是样式(display),切换当前DOM的显示和隐藏,适用于需要非常频繁切换条件的场景
- v-if: 当条件不成立时,不会渲染DOM元素,适用于不需要频繁切换条件的场景
使用 VUE 中的 v-for 时为什么要用 key
答案
普通版
- 为了快速的找到新节点对应的旧节点,
key
是给每一个vnode
唯一的id
, 可以依靠key
,更准确、更快的拿到oldVnode
中对应的vnode
节点,如果不使用key
时也可以运行,但是会报warning
说说 VUE 中 VUEX
答案
普通版
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,VUEX有5个核心属性
- 5个核心属性分别为:
state
:状态中心getters
:获取状态mutations
:更改状态actions
: 异步更改状态modules
:将state
分成多个modules
,便于管理
说下 VUE 如何优化
答案
普通版
- 1、路由懒加载
- 2、图片懒加载
- 3、区分
v-show
和v-if
使用场景 - 4、区分
v-for
和v-if
不要一起使用 - 5、区分
v-for
避免使用index
作为key
- 6、提取公共样式
- 7、第三方插件按需加载
- 8、
computed
和watch
区分使用场景
写简历建议
写项目经验的时候,记得写上项目用了那些技术点,写你所掌握的,方便面试官问你;不然面试官就会自己想面试题问了。写上去的技术点一定要掌握,设计的知识点也最好非常熟悉,因为面试会在你回答的时候,从你回答的一些答案当中挑出技术点去回答。
如果你有很多的好项目经验,可以都写上去,不要想着简历最好不要超过两张纸
面试建议
1、在去面试前,记得去查面试公司的相关信息,到公司后,在本子上写上该公司的信息(名称、地址)、什么时间面试的、公司给你的第一感觉如何
2、面试时,回答面试题时要回答详细点,加上自己的理解;不要一直让自己处于被问的状态,最好抓住你抓掌握的点,去跟面试官讨论,或者有些你不是很清楚的去问面试官;
3、面试后记得把没有回答上的面试题或者回答得不是很深的面试题记上本子上,并写上面试上所了解的公司信息
4、在去下一家公司面试的路上开始查找记录的面试题并进行深度的理解,并思考这家公司是否符合自己的心里预期,好方便后面的选择
5、晚上到家后,对整天的面试进行复盘,如言行举止、面试时回答是否回答得体
个人面试笔记模板
进阶篇链接
- JS执行过程详解,从编译到垃圾回收
- 从 8 道面试题看浏览器渲染过程与性能优化
- (1.6w字)浏览器灵魂之问,请问你能接得住几个?
- 三刷红宝书之 JavaScript 的引用类型
- 「一道面试题」输入URL到渲染全面梳理中-页面渲染篇
- 猛增 110K Star!年增长数最多的 10 大顶级前端学习资源项目!/a>
- JavaScript进阶
- 看懂此文,手写十种Promise!
- 以前我没得选,现在我只想用 Array.prototype.reduce
- JS 变量存储?栈 & 堆?NONONO!
个人收藏的面试题链接
- 🐮化身面试官出30+Vue面试题,超级干货(附答案)|牛气冲天新年征文
- JS手撕,经典面试题
- 面不面试的,你都得懂原型和原型链
- 中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂(上)
- Vue最全知识点,面试必备(基础到进阶,覆盖vue3.0,持续更新整理,欢迎补充讨论)
- 面试复盘(一):认清现实
- 17K star 仓库,解决 90% 的大厂基础面试题
- JS基础知识(覆盖JS基础面试题)
感谢
如果有错误或者不严谨的地方,烦请给予指正,十分感谢。如果喜欢或者有所启发,欢迎点赞,对作者也是一种鼓励。