前端面试题汇总

425 阅读15分钟

vue方面

谈一谈对diff算法的理解

  • what(diff是什么)::diff是一种算法,是一种虚拟dom出现之后,由虚拟dom计算出真实dom时的所需要一种最小的操作。

  • why(为什么要使用diff):性能高、兼容性、跨平台。

  • where(在哪里用到了diff):两个节点在进行patch的时候,这个时候就需要用到diff了,patch Vnode,主要作用是能够比较出变化,当存在新旧虚拟dom的时候,会使用diff,如果不存在只是一次新增行为,那是初始化,现在说的是新旧dom都存的时候会用到diff.

  • how(diff是怎么比较的):(总分总的答法:)

    • 深度优先,同级比较。
    • 首先从顶层节点开始比较,如果是元素,那就看他们有没有孩子,如果有孩子,就向下递归,这就是深度优先,在向下比较的过程中,可以给您介绍下重排算法,假设有4种可能性:
      • 1、假设新旧节点首位节点相同,则新旧节点index都加1,再向后依次进行比较。
      • 2、新旧节点尾部元素相同,则新旧节点index都减1,再向前进行比较。
      • 3、旧节点的首位节点与新节点的尾部节点相同,则旧节点首位节点移到队尾,index加1 进行比较,新节点index减1再与旧节点进行比较。
      • 4、旧节点尾部节点与新节点首位节点相同,则旧节点尾部节点移到队首,index减1,新节点index加1 再进行递归比较。
      • 若这四种情况都不符合,则只能在新节点中循环遍历节点去老节点中找是否有相同的节点,如果找到,则需要进行重排,并进行打补丁操作(patch)。在这个过程中,则才说的4种情形有可能会重复,因为比较的这个节点也可能有子节点,这样就需要进行递归操作。

vue生命周期

  • beforeCreate: 在实例初始化之后,数据观测(data/observer)和event/watcher事件配置之前被调用。
  • created: 实例创建完成后被立即调用,数据观测、属性和方法的运算,watch/event事件回调,但是挂载阶段还没开始,$el不可见。
  • beforeMouted: 挂载开始之前被调用,render首次被调用。
  • mouted: el被新创建的vm.$el替换,并挂载到实例之后调用该钩子,
  • beforeUpdate: 数据更新前调用,发生在虚拟dom打补丁之前,这里适合在更新之前访问现有的dom. 如手动移除添加的事件监听器。
  • updated: 组件dom已经更新,这里可以执行依赖于dom的操作。
  • activated: keep-alive组件激活时调用。
  • deactivated: keep-alive组件停用时调用。
  • beforeDestroy: 组件实例销毁时调用。在这一步,实例仍然可用。
  • destroyed:vue实例销毁后调用,调用后,vue实例所有的事件绑定都会被移除。所有的子实例也会被销毁。

keep-alive在哪个生命周期中执行?是怎么做的?

keep-alive在activated这个生命周期中执行,被包裹在keep-alive中的组件状态将会被保留,例如一个选项卡,如果在一个选项卡中滑到了100条数据,如果切换到别一个tab中,再切换回原来的tab,还会在原来滑到100条数据的位置。

父子组件的渲染及更新顺序

一、 加载渲染过程

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

二、子组件更新过程

父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated

三、父组件更新过程

父beforeUpdate -> 父updated

四、销毁过程

父beforeDestroy -> 子beforeDestory -> 子destoryed -> 父destroyed

组件间通信

一、父子之间通信:
  1. 父组件向子组件传值:props,可以是对象或数组。
  2. 子组件向父组件传值:emit()函数可以传参数。父组件通过emit()函数可以传参数。父组件通过on()触发自定义事件。
二、多层级嵌套需要传递数据时使用vuex

vuex:vuex提供了一个单向数据流,在全局有一个state存放数据,当组件要更改state中的数据时,必须提交一个mutation,action也可以修改状态,但是可以异步操作的。 action与mutation的区别:

  1. action提交的mutation不是直接修改状态的.
  2. action可以包含异步操作,而mutation不行。
  3. action中的回调函数第一个参数是context,是一个与store实例具有相同属性的方法的对象。
  4. action通过store.dispatch触发,mutation通过store.commit触发。
三、$attrs/$listeners

vuex主要是多层级嵌套时传递数据的,如果仅仅是传递数据,那用vuex就有点大材小用了。这时候使用$attrs就可以。

  1. $attrs:它包含了除props中的所有(除class和style)的所有属性,当一个组件没有声明任何props时,那这里会包含所有父作用域中的绑定(除class和style外),通常用v-bind="$attrs".
  2. $attrs中存入所有非props属性,$listeners中存放了父组件中非原生事件。
四、provide/inject

provide/inject这两个必须成对使用。允许祖代组件向后代组件中注入依赖,不论组件嵌套层级有多深。即:祖先组件中通过provide提供变量,然后在子孙组件中通过inject来注入变量。

谈一谈对vuex的理解。

  1. 数据都存在state中。
  2. 想要修改状态必须提交mutation.通过store.commit提交。
  3. action可以实现异步提交mutation。通过store.dispatch触发。
  4. getter相当于计算属性,在这里对state中的数据进行计算重组。

vue项目怎么优化?

  1. v-for和v-if尽量不要一起使用。如果非要一起使用,先在computed中把数据过滤一下。
  2. 路由懒加载。
  3. 图片懒加载。
  4. keep-alive缓存组件。
  5. v-show重用组件。
  6. 事件销毁。
  7. 第三插件按需引入。
  8. 子组件分割,让子组件管理自己的渲染。

如何提升首页的渲染速度?

  1. 路由懒加载。这样就不会在首页渲染的时候加载所有的组件,会在路由被访问的时候才加载。
  2. 图片资源过大,实现图片懒加载。
  3. 禁止线上生成的map文件。
  4. 启用ngix中的gzip压缩功能。
  5. 对于一些通用的工具库可以采用CDN的方式引入。
  6. 优化代码逻辑,组件化,模块化,增加组件的复用性。精灵图。

说一说对$nextTick的理解?

vue.nextTick() 在下次DOM更新循环结束之后执行延迟回调,获取更新后的DOM.当数据变化后,如果想快速的获取dom可以利用nextTick的回调函数。另外还可以说一下js的event-loop(事件循环)。宏任务、微任务。

vue中的修饰符有哪些?

表单组件的修饰符:
  1. .lazy: html <input v-model.lazy="msg"/> v-model默认会在input事件触发后将输入框的值与数据进行同步,使用.laxy修饰符可以在使用change事件时将输入框的值与数据进行同步。
  2. .number: html <input v-model.number="num" type="number"/>如果想让用户每次输入的值都转化为数字,可以使用.number修饰符。
  3. .trim: html <input v-model.trim="msg"/> 自动过滤用户输入的空白字符。
事件修饰符
  1. .stop:html <a @click.stop="click"></a> 阻止单击事件继续传播。
  2. .prevent:html <form @submit.prevent="onSubmit"></form> 提交表单不再重载页面。
  3. .capture: html<div v-on:click.capture="doThis">...</div> 添加事件监听时使用事件捕获模式。
  4. .self:html <div v-on:click.self="doThat">...</div> 只当在event.target是当前元素自身时触发处理函数。
  5. .once:html <a v-on:click.once="doThis"></a> 点击事件只会触发一次。
  6. .passive:html <div @scroll.passive="onScroll" >...</div> 滚动事件的默认行业为(即滚动行为)会立即触发,而不会等待onScroll完成,.passive会告诉浏览器你不想阻止事件的默认行为。

vue双向数据绑定原理。

vue响应式原理。

如果想扩展某个现有的组件怎么办?(vue.mixin)

vue.mixin 可以扩展组件,

你怎么理解路由嵌套。

如果要扩展一个element-ui的表格,去根据关键字去查询出所需的列表怎么做?

如果在data中增加一个属性会发生什么? 从数据响应式的方向去回答。

js中渲染DOM与vue中渲染DOM的区别。

js中的数组copy与vue中的数组拷贝有什么区别?

谈一谈对MVC与MVVM的区别?以及MVVM解决了MVC的哪些问题?

vue项目的权限控制怎么做?左侧显示菜单?在什么存入vuex及localStorage中。

js部分

js中闭包?

在一个函数中创建另一个函数就创建了闭包。闭包有权访问其外部作用域中的变量。闭包的作用:

  1. 闭包可以用来模拟块级作用域,用立即执行一个函数,来使外部不能访问立即执行表达式中的变量。
  2. 闭包可以用来创建访问对象中的私有变量的公有方法。
  3. 可以创建单例。

js中的继承有哪几种?

  1. 原型链的继承:
function Parent(name) {
  this.name = name
  this.colors = ['red', 'green']
}
Parent.prototype = {
  constructor: Parent,
  sayName: function () {
    console.log(this.name);

  }
}

function Child(name) {
  this.name = name
}

Child.prototype = new Parent()

let child = new Child('Mike')
child.sayName()   //Mike
//接下来说原型链继承的缺点:
var child1 = new Child('Mike')
child1.colors.push('blue')
console.log('child1.colors:==', child1.colors);  //["red", "green", "blue"]

var child2 = new Child('Mike')
console.log('child2.colors:==', child2.colors);//["red", "green", "blue"] */
  1. 构造函数模式的继承
//借用构造函数的继承方法
function Parent() {
  this.colors = ['red', 'green']
}

function Child() {
  //继承了Parent
  Parent.call(this, 'lily')  //this指向Child构造函数
  //这样做其实是在Child的实例中调用了Parent的构造函数,这样就会在新Child对象上执行Parent构造函数中定义的所有对象初始化代码,
  //结果每个Child实例就会有colors的副本了。同时也向Parent中传递了‘lily’参数
}

var child1 = new Child()
child1.colors.push('blue');
console.log('child1.colors:==', child1.colors); //["red", "green", "blue"]

var child2 = new Child()
console.log('child2.colors:==', child2.colors); //["red", "green"]
  1. 构造函数模式与原型模式相结合 在子构造函数中用call调用父构造函数,并且可以传值,然后再把父的实例赋值给子的原型:即Child.prototype = new Parent()
function Parent(name) {
  this.name = name
  this.colors = ['red', 'green']
}

Parent.prototype.sayName = function () {
  console.log(this.name);

}

function Child(name, age) {   //构造函数继承
  Parent.call(this, name)
  this.age = age
}

Child.prototype = new Parent()   //原型链继承

Child.prototype.sayAge = function () {
  console.log(this.age);

}

var instance1 = new Child('Mike', 27)
instance1.colors.push('blue')
console.log(instance1.colors);  //["red", "green", "blue"]
instance1.sayAge()   //27

var instance2 = new Child('Lily', 29)
console.log(instance2.colors);  //["red", "green"]
instance2.sayAge()   //29
  1. 原型式继承:
var person = {
 name: "Nicholas",
 friends: ["Shelby", "Court", "Van"] };
 
 var anotherPerson = Object.create(person); 
 anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = Object.create(person); 
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"

//Object.create()的方法实现如下:
function object(o) {
  function F() { }
  F.prototype = o;
  return new F();

}

js中的阻止默认事件和冒泡分别是什么?

vent.preventDefault() event.stopPropagation()

call,apply,bind的区别与联系?如果bind()之后再执行bind()会改变原函数的this指向吗?

call,apply,bind都是修改this的指向的。call(this,参数列表),apply(this,参数是数组),bind(this,参数列表),但是bind返回的是新函数,需要再调用才能修改this指向。

//调用两遍bind会改变原来函数的this指向吗
let obj = {
  name: 'mike'
}
let foo = function () {
  console.log(this);
}


let bind1 = foo.bind(obj);
bind1()   //obj
let bind2 = bind1.bind(obj);
bind2();  //obj
console.log('bind1:', bind1);
console.log('bind2:', bind2);
//由上面的代码可知,调用两次bind不会改变this的指向。因为调用bind之后只要传入的第一个参数是obj,那this就一定指向obj,再者调用bind之后就返回 了一个新的函数,与原来的foo函数已经没有关系了。

js中的数组copy与vue中的数组拷贝有什么区别?(深拷贝与浅拷贝)

其实是一样的,这里可能是想问如何处理vue中如果多个组件都用了同样的数组对象,如果希望各组件中的数据对象相互独立,应该怎么处理?

computed: {  
     data: function () {  
         var obj={};  
         obj=JSON.parse(JSON.stringify(this.templateData)); //this.templateData是父组件传递的对象  
         return obj  
    }  
 }

js中的作用域。

如果在作用域中声明了很多相同的变量是替换它的值还是整个都替换。

替换值

js中的数组copy与vue中的数组拷贝有什么区别?

浏览器从你输入url是怎么渲染页面的?

vue.delete与js的delete的区别?

vue.delete删除对象的属性,如果这个属性是响应式的,确保删除能更新视图,这个方法主要是用于vue不能检测到属性被删除的限制,它的目标对象不能是一个vue实例或vue实例的根数据对象

js数组中的增加和删除元素的方法?

  1. pop():删除数据的最后一个元素,并返回删除的元素。
  2. push():在数组的尾部增加一个或多个元素,并返回数据的长度。
  3. shift():删除数组的第一个元素,并返回第一个元素的值。
  4. unshift():将参数添加到原数组的开头,并返回数组的长度。
  5. concat():把两个数组合并到一个数组中,并返回一个新数组。
  6. join():将数组中的所有元素放入一个字符串。
  7. splice():向数组中添加或删除项目,然后返回被删除的项目。

饿了么

1. fiber react的高阶组件。

2. hook 高阶组件。

3. 怎么理解前后端分离? 仅仅是前后端并行开发就是前后端分离了吗?

4. 写过什么node的中间件?或koa2中间件?

5. koa2与express比有什么优势吗?koa2的洋葱模型有什么优点?

6. 强缓存与协议缓存有什么区别?www.jianshu.com/p/9c95db596…

7. 移动端怎么进行优化?怎么加快页面渲染速度? 从加载和渲染的角度分别解释。

8. PWA有了解吗?

9. 如果有一个中台项目,左侧有菜单,有菜单1和菜单2,分别属于不同的项目,有可能是菜单1是react写的,菜单2是vue写的,通过import引入到这一个中台项目中,从菜单1和2点击分别进入不同的项目,如果这个中台项目中有菜单变化了,怎么通知这所有的菜单项目。

(18年出的微前端 single SPA)

10. 说一下对虚拟DOM的理解?

11. 利用node怎么提高程序的稳定性?

12. koa2中有这样的一个程序:代码1,代码2,代码3,代码4,依次执行,如果代码3想用代码4的执行结果,怎么办?

13. cookie缓存,主程序能访问子域的cookie吗?反过来,子域能访问主域的cookie吗? passport怎么实现单点登录。

cookie是一个可以存放4kb的小型文本数据。localstorage一般浏览器可以接受5M的大小。一级域名可以访问二级域名的cookie,但是两个二级域名之间不可以相互访问的。比如aa.baidu.com与bb.baidu.com这两个二级域名之间的cookie是不能相互访问的,但是给cookie的domain设置为.baidu.com,那么aa.baidu.com与bb.baidu.com就能访问同一个cookie了。path设置为‘/’是允许所有路径都可以访问cookie。

美团点评

1. 防抖和节流用过吗?有什么区别?什么是防抖和节流?

2. 301和302有什么区别?

3. 有了解过BFC吗?

4. 移动端怎么解决1px的误差?rem可以设置的html的font-size的最小字体大小 ?

参考链接:www.jianshu.com/p/3a262758a…

5. 用过哪些技术做移动端?

6. call,apply,bind的区别?如果连续调用两次bind会改变this指向吗?

7. js的跨域解决方案?(jsonp ngix反向代理 CORS:后端设置cross-origin:*)

8. https怎么做?

9. git的命令:xmrry patch

10. 怎么管理线上分支?

11. 如果有一个长列表数据,怎么让它快速的渲染,不占用太多渲染时间?

12. 怎么对网站进行https化?

参考链接:yq.aliyun.com/articles/59…

13. 怎么开发chrome扩展程序?

www.cnblogs.com/liuxianan/p…

14. vue的自定义指令。

15. 浅拷贝与深拷贝。怎么实现深拷贝?

16. promise的then是怎么实现的?

中企动力

1. seo 工具有用过哪些?tailer用过吗?

2. 如果子组件中有数据与父组件中通用,用$attrs能实现吗?

3. 做过哪些通用组件?弹出框

4. 动态路由?路由是从后端请求过来的,这时候怎么做动态路由?不要在前端写死

5. vue.extends()用过吗?

6. vue slot用过吗?

7. 用原生js写一个轮播?

8. 有一个树状结构数组,怎么样用递归实现把有叶子节点并且是可编辑的数据给保存下来?递归最重要的就是判断和return.

9. 说一下cookie、localStorage、sessionStorage。

10. 用过哪些h5的技术(rem,bootstrap,mpvue)。

11. 写过多端通用的程序吗?比如微信小程序、qq小程序、百度小程序、支付宝小程序、京东小程序。

12. 怎么实现单点登录?

13. 如果一个项目运行过一段时间,变得非常慢,怎么进行优化。

14. 用过uni-app吗?

15. vue怎么做兼容性?兼容ie9,ie11,(用babel-polyfy)

16. 怎么做项目静态化?

17. 怎么用nginx做负载均衡?

杂项

1. 路由守卫有哪几种?分别适用于什么场景?

2. vue实现路由有哪两种方式?history和hash,两者的区别是什么?history不能记住前进和后退吗?

3. 有三个页面组件a,b,c,操作的跳转顺序是从a到b再到c,那怎么样操作能直接从a跳转c,或从c直接跳转到a,不记录中间的b的顺序?(用replace({path:'/a'}))

4. 谈谈vuex,怎么把vuex中的数据持久化,因为一刷新页面状态就没了。(存在localStorage)

5. Vue双向数据绑定原理。

6. app与web之前的交互做过吗?(kafka)

7. 后台有很多机子,怎么监控接口调的哪台机子?怎么知道调的是后台的哪个接口?一般来说在network中看到的只是通过koa转发的接口,(通过文档和查程序的方式)

8. 用过哪些koa的中间件(koa-router/koa-bodyparser/koa-views)

9. 说一下防抖和节流。

10. cookie跨域怎么处理。(domain和sso单点登录)

11. 怎么优化长列表数据,使渲染和性能提升。v-lazy图片懒加载的原理。

12. rem的原理。(不同屏幕尺寸的html的font-size不同)

13. 用过哪些es6的特性。

14. async函数返回什么?(返回Promise)

15. set与Map的区别。

16. vue项目性能优化。

17. 用webpack时一般都怎么配置。

中商惠民

1. 做过哪些公共组件?

2. es6的class的继承,怎么在子类中使用父类的方法?

3. 使用es6怎么定义多态?怎么在函数的参数不同时使用函数的不同功能?

4. es6中class的super的作用是什么?

5. 有哪几种slot? 什么场景下需要使用slot?

6. 最近在学什么新的技术?

7. es6中的class怎么实现多态?