面试题

最近公司有要招人,然后叫我负责一下技术方面的面试,然后问着问着,好像发现有一些知识点我也不是记得特别清楚。所以有必要列一下自己面试需要问的问题,并且把所有问题点给摸索清楚。不然被问住了就很尴尬了。。。

HTML

初级

1. HTML5有哪些新特性,你用过哪一些?

语义化标签、audio、video、canvas、geolocation、web worker、websocket

cookie、localStorage、sessionStorage的区别

cookie:每次请求都会被发送到服务器。不大于4k。可以自定义过期时间;服务端可以设置httponly,前端不可访问。
sessionStorage:页面关闭后失效(window.open新页面还会存在)
localStorage:永久存储

中级

如何在移动设备实现物理1像素的线

单边:1px的线然后再缩放 dpr 倍
四边:实现一个与目标元素dpr倍宽、dpr倍高的伪元素,然后整体缩放dpr倍。让其刚好覆盖到目标元素上。(兼容圆角)

网上的方案还有:border-image、viewport+rem、box-shadow来实现。但是最实用的还是上述方法。

升级:结合vue的指令可以更优雅的实现一像素问题。见项目笔记

高级

如何在页面间传值

  1. 监听storage事件,获取localStorage、sessionStorage 变化,从而传参(跨域限制)
  2. postMessage(无跨域限制、可用于iframe、openner)
  3. sharedWorker(高级、兼容性差)

CSS

初级

css选择器有哪些?以及他们的优先级

1.id选择器( # myid)
2.类选择器(.myclassname)
3.标签选择器(div, h1, p)
4.相邻选择器(h1 + p)
5.子选择器(ul > li)
6.后代选择器(li a)
7.通配符选择器( * )
8.属性选择器(a[rel = “external”])
9.伪类选择器(a:hover, li:nth-child)

id > class > 属性 > 标签 > 通配符

解释一下rem、em、px、vh、vw的区别

  • rem:相对于\font-size:来定义的单位。
  • em:相对于父元素的font-size 来定义的单位
  • px:物理像素,基本单位
  • vh:100vh === 1浏览器可视区域高度
  • vw:100vw === 1浏览器可视区域宽度

高级:

  • vmin:相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin
  • vmax:相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax
  • rpx:微信小程序使用的单位,750rpx等于屏幕宽度

对盒子模型的理解,IE盒子模型和标准模型有什么区别

盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border)

其实区别在于box-sizing属性:

content-box:标准盒子模型;
border-box:IE盒子模型;content部分把 border 和 padding计算了进去

中级

高级

JS

初级

js基本数据类型

undefined、null、boolean、string、Number、Symble(ES6)

事件冒泡与事件捕获的区别

IE使用的是事件冒泡、另一种是事件捕获

事件冒泡:事件开始于最具体的元素、然后逐级向上传播到较为不具体的节点

事件捕获:由不太具体的节点应该更早接收到事件、而最具体的节点最后接收到事件

通过addEventListener的第三个参数来启用监听事件冒泡还是事件捕获:true,事件捕获;false:事件冒泡;所以平时使用的都是false居多

场景提问:如果有一个列表,有数千个选项要绑定事件,应该如何处理;

判断一个变量是不是function

typeof variable === ‘function’

是不是array

Object.prototype.toString.call(variable) === ‘[object Array]‘

中级

宏任务与微任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
console.log(1);

setTimeout(() => {
console.log(2)
}, 0)

new Promise(resolve => {
console.log(3)
resolve()
}).then(() => {
console.log(4)
});

console.log(5)

打印顺序:1、3、5、4、2

setTimeout是宏任务,Promise是微任务,微任务会比宏任务快,可以简单的理解,微任务是vip吧;

概念大概是这样的:js有个执行堆栈和排队队列的概念。如果是同步任务,则直接进入堆栈。如果是异步任务,则进入队列等待;
如果堆栈为空,则先查找微任务内的队列任务,再去查找宏任务的队列任务;

比较特殊的是,Node的process.nextTick();和前端的MessageChannel(Vue的nextTick是利用MessageChannel来实现的)。该方法是直接把任务插入到堆栈底部,会比微任务与宏任务都快;

属于微任务的有:Promise、MutationObserver、process.nextTick(Node)

箭头函数与普通函数的区别

  1. this指向不一样。无法通过call、apply、bind从新修改this
  2. 没有arguments、也没有caller和callee;
  3. 不可以使用new 命令,会抛出错误
  4. 不可以使用yield命令,因此不能用作 Generator 函数。

高级

Set和Map数据结构

Vue

初级

组件的生命周期,加上keep-alive、vue-router之后会新增什么钩子函数

beforeCreate、created、beforeMounte、mounted、beforeUpdate、updated、beforeDestroy、destroyed

keep-alive第二次进入不会触发beforeCreate、created、beforeMounte、mounted、beforeDestroy、destroyed
新增activateddeactivated

加上vue-router之后会新增:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

created与mounted的区别,能不能在created里访问dom

created是组件实例加载完成,可访问data、prop、methods等等

mounted可以访问除了created能访问的东西 + dom

不能再created里访问dom

keep-alive

从场景中提问:比如一个分页组件,已经跳转到第三页,然后跳转到其他路由,再跳转回来需要还保留在第三页,应该用keep-alive;

中级

vue-router的不刷新加载实现原理是什么

vue-router有两种模式:hash和history;

hash:修改window.location.hash时,不会发生页面刷新、会给路由历史新增记录。且可以监听hashchange来监听hash的变化,以此来实现页面不刷新渲染页面。

history:利用history.pushstate方法来实现。也是不刷新页面、给路由历史新增记录。更多的是,也可以修改url的相对路径且不发生页面刷新加载;然后可以通过监听popstate事件来实现监听路由变化。

自定义指令

通过Vue.directive全局注册自定义指令或者directives: {} 局部注册自定义指令;

自定义指令用于给某个dom扩展特定的功能,自定义指令当中允许对当前dom进行直接操作;

钩子函数:

bind:被绑定到元素时
inserted:绑定元素被插入到父节点时(仅保证父节点存在)
update:所在组件的vNode更新时
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
unbind:只调用一次,指令与元素解绑时调用。

钩子函数参数:

el:指令所绑定的元素,可以用来直接操作 DOM
binding:一个对象包含各种属性:name、value、oldValue、expression、arg、modifiers
vNode:
oldVnode:

minxins

在混入和组件数据冲突时以组件数据优先;

钩子函数会被合并、先调用混入的钩子函数

组件v-model

允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event

使用model选项可以修改默认的prop和event

model: {
    prop: 'checked',
    event: 'change'
  }

高级

Vue.use一个插件到底做了什么

Vue.use用于安装插件,该方法需要传入一个function或者一个对象。如果传入的是function,则调用function。如果传入的是一个对象,则调用对象中的install方法。

Vue.use还做了一件事是防止重复安装插件

Vue.extends

Vue.extends接受一个对象,与Vue、Vue.components接收的参数完全一致。返回的是一个构造函数(constructor);new 该构造函数则返回一个组件实例(instance)。
该实例与new Vue生成的Vm实例、Vue.components生成的组件实例完全一致;不同的是一份配置=》一份构造函数=》多份实例。从而实现复用;

其他

初级

在提升代码性能做过哪些事情

发散、很多

中级

解释import的各种用法的区别

1
2
3
4
5
6
7
import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

https与http的区别,怎样做到加密的

https是http + ssl;

然后:

  1. 客户端像服务器发送请求
  2. 服务器向客户端发送公钥
  3. 客户端先验证公钥有效性
  4. 通过后生成一个随机值(私钥),然后用公钥对随机值进行加密
  5. 服务器用公钥解析随机值,拿到私钥;这样双方都有了唯一私钥
  6. 则双方利用私钥对数据进行对称加密,进行数据传输

高级

CommonJs与ES6 module的区别

CommonJs:规范出来之前的野生规范,遵守CommonJS规范。在import规范出来之前被大规模使用

ES6 Module:ES6官方模块管理规范

使用:

  • import 必须写在模块头部,必须在模块最外层;require可以在任何地方require;可以export多个代码
  • 可以require export出来的模块;但是import不能引用module.export的模块;虽然可以,但是强烈不建议使用;只能定义一个modules.exports

原理:

  • import是引用;require是立即运行

webpack怎样实现tree shaking(去除不必要的代码)

应该结合ES6的imoprt、export、DefinePlug、sideEffects和uglifyjs-webpack-plugin来实现;

原理是,用import、export或者DefinePlugin来定义部分不能访问的代码。然后uglifyjs-webpack-plugin在压缩js时识别不能访问的代码,从而去除掉多余的代码;

而sideEffects可以参考:Webpack 中的 sideEffects 到底该怎么用