前端程序员必备的面试题整理

1,539 阅读4分钟

正在持续更新中... ,路过的朋友,可以点个赞,关注一下~~~

01,Promise原理?

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理,更强大。

promise有三种状态,等待态、成功态、失败态,当new一个promise实例对象的时候,传递两个对应的方法,onFulfilled,onRejected,并初始化当前的状态,当状态发生改变的时候便会触发对应的方法,成功-onFulfilled,失败-onRejected, 若状态一直没有改变,则一直处于等待状态,即当异步程序处理完了之后再改变状态,完成异步任务。

在整个过程中,牵扯到 promise的链式调用,以及异步的暂存(处于等待状态的先存储起来)与调用(状态改变便进行调用)

参考文档:

02,then可以链式调用,多个then时,如果走到下一个then的失败回调?

答:1,返回一个失败的promse 2,抛出一个错误

03,then可以链式调用,多个then时,如何终止下一个then的调用?

答:返回一个处于pending(等待)状态的promise

04,js的异步解决方案有哪些()?

  1. 回调函数(node,嵌套,err)。
  2. Promise。
  3. Generator+co。 co可以解决promise嵌套问题。
  4. generator+promise(promise嵌套问题)
  5. async+await 是Generator的语法糖

05,把一个伪数组变成真实的数组?

  • 使用扩展运算符... eg. [...obj] (需要保证obj是可迭代 )
  • 数组上的方法from, eg. Array.from()
  • 数组的slice方法,eg. [].slice.call(obj)

扩展运算符:需要保证obj是可迭代 Array.from不需要保证obj是否可迭代,内部会使它可迭代

06,使用过ES6中的哪些新语法(** 熟练使用ES语法)?

答:解构赋值 [] {} Map : 里面存储唯一的值 WeakMap Set ES6中的模块化 箭头函数 装饰器 模板字符串 数组中一堆方法 reduce map filter some every..... 对象中一堆方法 Object.key() Object.defindproty Objct.value Objtct.xxxx 类,继承 构造器 原型链 Proxy ---- defindprototy
Symbol ...

30,v-model是本质是?

v-model:是一个语法糖,本质是 :value@input

<Son2 :value="counter" @input="newValue=>counter = newValue"></Son2>

<Son2 v-model="counter"></Son2>

31,说一下vue中的生命周期?

beforeCeate 实例化vue后,走的第一个钩子,此时还没有数据劫持 created vue实例已经创建完成,数据侦测OK,methods,computed也OK了,el不OK
`beforeMount`  挂载之前  
`mounted`el OK
beforeUpdate data改变了 准备渲染视图 domdiff updated 渲染视图完毕 不要去修改data,可能死循环 beforeDestroy vm销毁之前调用 destroyed 销毁之后调用

32,在vue的钩子,通常会做哪些事情?

  • created vm已创建完成 发起ajax请求
  • mounted vm已挂载完成 发起ajax请求 操作dom
  • beforeUpdate 再近一步去修改状态 不会重新渲染
  • updated 不能修改数据
  • beforeDestroy 优化操作,清空定时器,解除事件绑定

33. vue的生命周期具体适合哪些场景?画出vue的生命周期?

Vue生命周期在真实场景下的业务应用

  • created:进行ajax请求异步数据的获取、初始化数据

  • mounted:挂载元素dom节点的获取

  • nextTick:针对单一事件更新数据后立即操作dom

  • updated:任何数据的更新,如果要做统一的业务逻辑处理

  • watch:监听数据变化,并做相应的处理

vue的生命周期

34. vue实例上的属性?

vm.$data:Vue 实例观察的数据对象 vm.$options:用于当前 Vue 实例的初始化选项。 vm.$nextTickvm.$el: 获取到真实的dom 获取到的可能不是更新后的 需要在下一下事件环中获取更新后的dom元素 vm.$watch: 监控一个数据 vm.$set: 将数据设置成响应式 vm.$delete: 删除对象的属性。

35. 为什么通常不使用index作为key?

key的作用

作用:高效的更新虚拟DOM,key是给DOM添加唯一的标识,当元素发生改变的时候,通过domdiff算法,做到更小更新,提高性能。 概括说:改变的元素进行更新,不改变的不更新

原因

使用index作为key时,可能存在DOM元素没有发生改变,只是顺序发生了改变,但是此时的key的值就发生了改变,根据domdiff算法,就会更新所有key变化的DOM元素

例如:渲染一个数组,绑定index,作为唯一标识,当数据进行倒序排序时,DOM元素没变,顺序发生了改变,但此时DOM上的key发生了改变,就会重新进行渲染,浪费性能。

36. computed,watch,methods的区别?

  • computed:计算属性有缓存,如果计算属性所依赖的数据没有必变,它会去缓存中取
  • methods:方法是没有缓存,每一次拿数据,都会调用这个方法
  • watch:监控数据的变化,第1次编译没有触发 需要配合mounted钩子,或者使用immediate: true使第一次编译时触发

computed 和 methods的区别

  • computed有缓存
    • computed中的方法,主要是依据data中的数据生成的新的数据,里面的方法,在第一次编译调用之后便不再进行调用(数据不改变的情况下),即数据不更新便不再执行。
  • method没有缓存
    • 只要使用该方法便进行调用。

computed和watch有什么区别

  • 大多数情况下,computed和watch都可以互换,
  • watch中可以写异步,
  • watch中的写法复杂一点,
  • watch可以实现一些简单的功能

watch和方法有区别?

  • watch主要是用来监控数据变化
  • 方法里面就是写一些常规的方法
  • 两者没有太大的联系

特别提醒

能使用computed就不要使用watch

37. 项目中是如何封装axios?

  1. 发出请求,响应数据
  2. loading动画,携带请求头,处理响应数据(请求拦截和响应拦截)
  3. queue 避免同一个请求发出多次,(有动画时,也避免多个动画)
  4. cancelToken 切换到下一个页面时,把上一个页面相关的请求给取消(没有完成的)

38. 防抖节流的应用?

函数防抖(debounce): 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时;

典型的案例就是输入搜索:输入结束后n秒才进行搜索请求,n秒内又输入的内容,就重新计时。

函数节流(throttle): 规定在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效;

典型的案例就是鼠标不断点击触发,规定在n秒内多次点击只有一次生效。

39. vue中是如何缓存数据,避免重新请求接口数据的?

答:使用keep-alive,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。

40. 封装axios时,为什么会用到cancelToken来取消请求?

答:切换页面的时候,可能上个页面的请求还没有请求完,取消上一次的页面中的请求,提高性能

41. 项目中记录页面中的位置信息,一般保存在什么地方?

答:浏览器的 sessionStorage

42. vue页面中有一万条数据,你是怎么给它渲染出来的?

答:采用分页渲染,如不能分页,使用虚拟列表(长列表),类似cubeui中的RecycleList长列表渲染

参考文档

43. vue中的项目是如何优化的?

答: 代码角度的优化 ;性能角度的优化;用户体验角度的优化

可以参考具体的优化方案:

44. 首页出现白屏,是怎么解决的?

答:

  1. ssr 服务端渲染 需要写代码 有Nuxt框架
  2. 如果页面内容不经常变动,如公司官网,可以使用预渲染 配置
  3. 可以配置骨架屏(常用)

45. 简述vue-router的原理

  1. 自定义一个 vue-router 类,该类中规定必须有一个install的静态方法
  2. 引入自定义的vue-router,并在vue中使用这个中间件,当使用Vue.use时,便会自动的调用vue-router中的install(Vue)静态方法,并将所有的组件作为参数依次传入。

import VueRouter from "./vue-router" Vue.use(VueRouter);

  1. install静态方法中,使用Vue.mixin()为每个组件都混入一个beforeCreate方法,在beforeCreate方法中,若是main根组件,则将main.js中的参数router挂载到自身_router上,并将自己挂载到自身的属性_root上,若不是根组件,则将父组件的_root挂载到自身的_root,(此处类似于递归设置)
  2. beforeCreate中为每个组件都添加一个 $router$route的属性,$router指向自定义vue-router 中的静态方法;$route指向当前存放对的路由里面的属性
  3. 在自定义的vue-router中设置一个构造器,用于接收new 自定义vue-router时传递的参数(mede,router....),转换路由格式,并且处理不同的路由模式(hash,history),将处理后的当前路由进行保存
  4. 在install(Vue)中定义全局的router-link组件,使用属性传值与匿名插槽定义,显示的路由,当点击时进行跳转
  5. 在install(Vue)中定义全局的router-view组件,获取当前路由,与路由表,相比对,进行渲染

vue-router 原理 图示

enter description here