关于初级前端工程师在面试中会遇到的一些面试题(一)

448 阅读9分钟

1. 父子组件的生命周期加载渲染

要了解父子组件的生命周期加载渲染。首先,我们来谈谈组件的生命周期

生命周期

在创建VUE实例之后,都会经过一段初始化过程,即数据监听、编译模板、挂载DOM、更新DOM等。

在声明周期中,有一些生命周期钩子的函数,用来在不同的加载阶段添加代码书写。

beforeCreate()

在初始化实例之后,data初始化之前被调用,还无法访问methods、data、computed中的数据

created()

已完成了数据的初始化,但是el还未挂载。在created中,可以访问并改变数据和方法

beforeMount()

首次调用render函数(虚拟DOM),已经完成了数据和html的初始化,但是还没有挂载到浏览器上

mounted()

html渲染挂载完成,也可以执行ajax操作(但是只执行一次)

beforeUpdate()

数据更新之前被调用,在该钩子函数中,可以更改状态且不会触发额外的重渲染过程

updated()

数据和DOM都已经重新更新,大多数情况下,尽量不在其中更改状态,因为可能会导致更新无限循环,且在服务器渲染期间该钩子函数不会被调用

beforeDestroy()

在实例销毁之前调用,还可以进行操作:

  1. 使用this获取实例
  2. 清楚组件中的定时器或者监听的DOM事件

destroyed()

在实例销毁之后调用,在服务器渲染期间该钩子函数不会被调用

父子组件的生命周期

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

子组件如果被keep-alive包裹的话,会触发activated阶段

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

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

2. computed与watch的区别

computed计算属性的特点

  • 支持缓存,依赖的数据发生了变化,才回重新进行计算
  • 不支持异步,当computed中有异步操作时,数据的变化是无法监听到的
  • computed中的值是来自于data中已声明的值或者是从props中拿到的值进行计算得到的
  • computed中,使用get方法和set方法,当computed属性值是函数时默认走get方法,当数据变化时,默认使用set方法
  • computed多用于多对一或一对一的关系

watch监听属性的特点

  • 不支持缓存,数据跟随着变化而变化
  • 支持异步操作
  • 监听的函数有两个参数,一个是新值,一个是输入之前的值
  • 监听的数据必须是已经声明过得数据(data中或者是props中存在)
  • 一对多
watch: {
    watchTest: {
       handle(newName, oldName) {
         this.name = newName + oldName
    },
    immediate: true, // 组件加载时立即触发回调函数(handle)的执行
    deep: true, // 深入观察,给对象的所有的属性都加上监听器
  }
}

3. v-show与v-if

v-show

v-show其实是控制css中的display,只会编译一次

v-if

v-if是动态的在DOM树上进行元素的添加和删除,但是v-if比较消耗性能

共同点

两者显示的都是对于元素的显示与隐藏

4. 浅谈vuex

vuex是Vue的状态管理工具。vuex一共有五个核心模块:

  1. store 用来存放数据状态
  2. mutations 对于store中的数据的操作,用commit调用,(state, payload)
  3. getters 对store中的数据进行加工return,可以直接使用
  4. actions 异步操作,用dispatch调用,(context, payload)
  5. modules 模块化状态管理,将store分成不同的模块,每个模块都拥有store、mutations、getters、actions

5. 浅谈Cookie

什么是cookie

cookie一般用于服务端来判断用户的状态。当客户端访问服务端时,服务端会传送一个cookie给客户端并存放在浏览器中,当下一次打开浏览器时,客户端会将cookie传送到服务端,服务端据此判断用户的状态。

cookie的机制

客户端HTTP请求服务端--->服务端response客户端携带cookie--->客户端HTTP请求服务端并携带cookie--->服务端reponse客户端

cookie中有一些属性值

  • NAME=VALUE:设置要保存的值
  • Expires:设置cookie的有效期 maxAge(s)(内值若为负数,则为临时cookie;内置若为0,则为删除cookie)
  • Domain:生成cookie的域名
  • Path:生成cookie的路径,/为所有路径
  • Secure:若设置该属性,则表示只有在SSH连接的时候才会返回cookie

6. localStorage与sessionStorage

共同点

可以在浏览器缓存中存储数据(字符串类型)

不同点

  1. localStorage中的数据可以存永久,而sessionStorage在浏览器关闭之后会随之删除
  2. 相同浏览器中的不同页面可以共享localStorage中的数据,而不同页面不可以共享sessionStorage中的数据

7. 原型与原型链

什么是原型链?

JS对象有一个指向原型对象的链条(proto),当访问一个对象的属性时,会顺着链条(链头:Object)一层一层网上寻找(就近原则),直到链尾。

为什么要使用原型链?

  1. 实现继承
  2. 链条上的内容都可以访问到,prototype可以实现原型的继承和属性的共享(引用类型)
  3. 避免了代码的冗余,可以随时调用共同的属性和方法
  4. 减少了内存

如何使用原型链?

proto:每个对象都存在的属性,链条一般的存在

prototype:构造函数的原型,只有函数才拥有

function doSomething(){}
console.log( doSomething.prototype );
var doSomething = function(){};
console.log( doSomething.prototype );

8. v-model原理

v-model只是一个语法糖,实质上是v-bind与v-on的事件绑定触发的。顺便一提,

数据的双向绑定

数据的双向绑定的实现是来源于Object.defineProperty()这个函数,通过这个函数可以监听到get和set事件

Vue的双向绑定是根据发布者-订阅者模式实现的。监听者Observer监听数据是否变化并在发生变化时告诉订阅者Watcher(利用Objec.defineProperty实现数据的劫持,再通过set和get方法通知订阅者),若更新则更新相对应的数据和视图。

而其中有一个解析器Compile,可以扫描和解析各个节点的相关指令(比如:v-model,v-on等),若存在节点,则初始化数据、视图和相信的订阅者Watcher。

9. v-on

v-on可以绑定多个事件,多个事件也可以单独多个v-on绑定

绑定事件同时又多个修饰符:prevent、stop、keyup、keypress、keypress等等

10. webpack有哪些常用的loader

一般,loader用三种方式进行配置:

  1. webpack.config.js
  2. 命令行参数
  3. 内联使用

常用的loader:

  1. css:style-loader、css-loader、less-loader、sass-loader、postcss-loader...
  2. 文件:raw-loader、file-loader、url-loader...
  3. 编译:babel-loader、ts-loader...
  4. 校验测试:jshint-loader、eslint-loader...

常用的Plugin:

  1. html-webpack-plugin 自动生成html文件,引用css和js
  2. extract-text-webpack-plugin 将js中引用的样式单独抽离成css文件
  3. DefinePlugin 编译时配置全局变量

11. webpack与vue、node间的关系

Vue的开发不依赖于Node,但是vue-cli里面集成的webpack是基于Node开发出来的,即webpack依赖于Node。

但是Node经常帮助前端开发实现工程化开发,NPM可以帮助开发过程中下载可用的插件。

12. webpack的打包流程

从初始化option开始-->开始编译-->从入口Entry中递归的分析依赖搭建-->解析各个模块位置-->构建模块-->将loader加载完成的module进行编译,生成AST树-->遍历AST,收集依赖-->优化-->输出到dist

13. 性能优化

  1. 减少HTTP请求(防抖debounce), 只触发一次
  2. 尽量使用字体图标icon和svg尽量代替图片图标
  3. 压缩打包(webpack)
  4. 不重复加载相同的内容(max-age)
  5. 图片延迟加载+响应式图片+css效果代替图片+图片压缩+webp格式的图片
  6. 减少重绘重排(某些页面操作导致页面需要重新排布和渲染)
  7. 减少事件委托(利用事件冒泡机制委托给父元素,使父元素担当事件监听的任务)
  8. 使用requestAnimationFrame实现视觉变化保证JavaScript在帧开始时运行
  9. 使用Web Workers在执行任务时不会干扰到页面
  10. 优化DOM树,利用gzip压缩文件
  11. Vue中利用Object.freeze()提升技能
  12. 组件懒加载
  13. 服务端渲染(SSR)和预渲染(Prerender)优化加载性能
  14. 负载均衡

14. 单页面首屏加载速度慢的解决方案

利用performance.timing或者DOMContentLoad计算首屏时间

  1. UI框架按需加载
  2. SSR服务端渲染,通过服务器生成html字符串再传送给客户端(Nuxt.js)
  3. GZIP压缩
  4. 减少入口文件体积:路由懒加载
  5. 压缩图片资源
  6. 静态资源本地缓存
  • 采用HTTP缓存,设置Cache-Control,Last-Modified,Etag等响应头
  • 采用Service Worker离线缓存
  • localStorage
  1. 修改config中的CommonsChunkPlugin的配置,将重复次数多的文件抽离出来放到公共区域,避免重复调用

15. 加载进度条

配合加载之前与加载完成之间,当页面加载到指定区域,则返回(n)%的进度结果(beforeSend、complete、success)

16. Vue为什么有些插件要使用use

使用Vue.use()就是调用的该组件的install方法,且内部传入的值只能是对象或者是函数

17. 浏览器缓存

明白浏览器缓存在一定程度上可以对项目进行优化。

缓存位置

  • Service Worker

    使用Service Worker,传输协议必须是HTTPS(保障安全),它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且其缓存是持续性的。

  • Memory Cache

    内存中的缓存,主要包含当前中页面中已经抓取到的资源。然而一旦关闭窗口缓存也会被释放出来。(但它对缓存资源毫不在乎)

  • Disk Cache

    硬盘中的缓存,会根据HTTP Herder中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。

  • Push Cache

    推送缓存,只在会话(Session)中存在,一旦会话结束就会被释放,而且缓存时间很短暂。

缓存

浏览器对于缓存的处理是根据第一次请求资源时返回的响应头来确定的。

强缓存

不会向服务器发送请求,直接从缓存中读取资源。通过设置两种 HTTP Header 实现:Expires(资源到期的时间)、Cache-Control(控制网页缓存)。

协商缓存

强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存。

  • 协商缓存生效,返回304和Not Modified,并继续使用缓存

  • 协商缓存失效,返回200和请求结果