前端经典面试题 | 青训营笔记

75 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天

最近各大企业的春招陆续开始招聘,从网上整理并摘抄了一些前端经典面试题

Vue

SPA

一、什么是spa

spa就是单页面应用程序或网站的模型,通过动态重写当前页面来与用户交互,在单页面应用中,所有必要的代码都通过单个页面的加载而检索,动态装载适当的资源并添加到页面中,不会导致页面重新加载,也不会跳转到其他的页面。

二、SPA与MPA的区别

MPA(multipage-page application),即多页面应用,翻译过来就是多页应用在mpa中,每个页面都是一个主页面,都是独立的,当我们在访问另一个页面的时候,都需要重新加载html、css、js文件。

单页应用与多页应用的区别

单页面应用(SPA)多页面应用(MPA)
组成一个主页面和多个页面片段多个主页面
刷新方式局部刷新整页刷新
url模式哈希模式历史模式
SEO搜索引擎优化难实现,可使用SSR方式改善容易实现
数据传递容易通过url、cookie、localStorage等传递
页面切换速度快,用户体验良好切换加载资源,速度慢,用户体验差
维护成本相对容易相对复杂

三、单页应用优缺点

优点:

  • 具有桌面应用的即时性、网站可移植性和可访问性
  • 用户体验好、快、内容的改变不需要重新加载整个页面
  • 良好的前后端分离,分工更明确

缺点:

  • 不利于搜索引擎的抓取
  • 首次渲染速度相对较慢

vue中v-show 和 v-if有什么区别?使用场景分别是什么?

一、v-show与v-if的共同点

  • 当表达式为true的时候,都会占据页面的位置
  • 当表达式都为false时,都不会占据页面位置

二、v-show与v-if的区别

  • 控制手段不同
  • 编译过程不同
  • 编译条件不同

控制手段:v-show实现隐藏的方法是为dom元素添加css代码 display:none,dom元素依然存在。v-if显示隐藏是将dom元素整个添加或删除。

编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中会合适的销毁和弓箭内部的事件监听和子组件;v-show只是简单的基于css切换

编译条件:v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当的被销毁和重建。

  • v-show 由false变为true的时候不会触发组件的生命周期

  • v-if由false变为true的时候,触发组件的beforeCreate、create、beforeMount、mounted钩子,由true变为false的时候触发组件的beforeDestory、destoryed方法

vue2 中data属性为什么是一个函数而不是一个对象

在vue实例中将data声明成一个对象或者函数都是可以的 但是在组件中将data声明成对象就会报错 为什么? 因为当我们在定义一个组件的时候,vue最终会通过Vue.extend()构建组件实例 模仿组件构造函数,定义data属性,如下:

function Component(){
	
}
Component.prototype.data = {
	count: 0
}

当创建多个组件实例的时候,修改A的data属性的值,对B的属性的值也会发生改变,因为其data共用一个内存地址,如果采用函数的形式,则不会出现这种情况(函数返回的对象内存地址并不相同)

vue组件可能会有很多个实例,采用函数返回一个全新的data形式,使每一个实例对象的数据不会受到其他实例对象数据的污染

动态的给vue的data添加一个新的属性会发生什么?怎么解决

数据更新,页面并不会刷新 为什么? 访问属性或者设置属性的时候都可以触发setter与getter 但是为对象添加属性的时候无法触发事件属性的拦截 原因就是一开始对象的属性被设计成了响应式数据,而我们自己新添加的属性并没有通过Object.defineProperty 设置成响应式数据

解决方案

vue 不允许在已经创建的实例上动态添加新的响应式属性 若想实现数据与视图同步更新,可以采取下面三种解决方案: Vue.set() Object.assign() $.forceUpdated

vue中组件和插件有什么区别

一、组件是什么

组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue中每一个.vue文件都可以视为一个组件

组件的优势

  • 降低整个系统的耦合度,在保持接口不变的情况下,我们可以替换不同的组件快速完成需求,例如输入框,可以替换为日历、时间、范围等组件作具体的实现

  • 调试方便,由于整个系统是通过组件组合起来的,在出现问题的时候,可以用排除法直接移除组件,或者根据报错的组件快速定位问题,之所以能够快速定位,是因为每个组件之间低耦合,职责单一,所以逻辑会比分析整个系统要简单

  • 提高可维护性,由于每个组件的职责单一,并且组件在系统中是被复用的,所以对代码进行优化可获得系统的整体升级

二、插件是什么

插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:

  • 添加全局方法或者属性。如: vue-custom-element
  • 添加全局资源:指令/过滤器/过渡等。如 vue-touch
  • 通过全局混入来添加一些组件选项。如vue-router
  • 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
  • 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如vue-router

三、两者的区别

组件: 很常见 .vue格式 插件: vue 插件的实现应该暴露一个install方法。这个方法的第一个参数是vue构造器,第二个参数是一个可选的选项对象

MyPlugin.install = function (Vue, options) {
  // 1. 添加全局方法或 property
  Vue.myGlobalMethod = function () {
    // 逻辑...
  }

  // 2. 添加全局资源
  Vue.directive('my-directive', {
    bind (el, binding, vnode, oldVnode) {
      // 逻辑...
    }
    ...
  })

  // 3. 注入组件选项
  Vue.mixin({
    created: function () {
      // 逻辑...
    }
    ...
  })

  // 4. 添加实例方法
  Vue.prototype.$myMethod = function (methodOptions) {
    // 逻辑...
  }
}

注册形式

组件注册

vue组件注册主要分为全局注册和局部注册

插件注册

插件的注册通过Vue.use()的方式进行注册(安装),第一个参数为插件的名字,第二个参数是可选择的配置项 Vue.use()

vue组件之间的通信方式都有哪些

组件通信的分类

  • 父子组件之间的通信
  • 兄弟组件之间的通信
  • 祖孙与后代组件之间的通信
  • 非关系组件之间的通信

图片

组件通信的方案

通过 props 传递 (父传子)
通过 $emit 触发自定义事件 (子传父)
使用 ref 
EventBus (兄弟组件通信)创建全局事件总线
$parent 或$root
attrs 与 listeners
Provide 与 Inject
Vuex

ES6

说说var、let、const之间的区别

简单、略 从以下几个方面回答: 变量提升 暂时性死区 块级作用域 重复声明 修改声明的变量 使用

JavaScript

两种数据类型

  • 基本类型 存放在栈中
  • 复杂类型 存放在堆中

两种类型的区别是:存储位置不同

一、基本类型

基本类型主要分为以下6种:

  • Number
  • String
  • Boolean
  • Undefined
  • null
  • symbol

null

表示一个空对象指针

二、引用类型

  • Object
  • Array
  • Function .....

Object

三、存储区别

基本数据类型和引用数据类型存储在内存种的位置不同:

  • 基本数据类型存储在栈中
  • 引用数据类型的对象存储在堆中

当我们把变量赋值给一个变量时,解析器首先要确认的就是这个值是基本类型值还是引用类型值