前端面试题总结

这两天电话面试了两家公司,总结一下遇到的面试题

ES6新增的一些特性

  • 新增了块级作用域,let和const
  • 新增了class用来定义类
  • 新增了一种基本数据类型symbol,symbol表示独一无二,允许设置默认值,不能用new关键字
  • 新增了结构赋值
  • 新增了箭头函数,引入了rest参数
  • 函数允许设置默认值
  • 新增了set和map数据结构
    • set可以用来快速去重
    • map的特点就是key可以是任意类型
  • 新增了模块化,import导入和export导出。
  • 数组新增了一些api,如 isArray(判断是否为数组) / from / of 方法;数组实例新增了entries(),keys() 和 values() 等方法
    • from()通过拥有length属性的对象返回一个数组
    • of()数组的静态方法 弥补了数组因为参数数量导致的行为差异(比如说只有一个参数3 newArray返回一个长度为3的数组,of(),则返回一个参数为3的数组 行为非常统一)
    • entries()返回一个数组的迭代对象,该对象包含数组的键值对
    • keys() 循环键
    • values()循环值
  • ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。
    • proxy在目标对象的外层搭建了一层拦截,外界对目标对象的某些操作,必须通过这层拦截。new Proxy()表示生成一个Proxy实例,它接收两个对象,第一个是要拦截的对象 第二是是用来定制拦截行为的。
  • 新增了生成器(Generator)和遍历器(Iterator)

ajax的优缺点

  • 优点

    1. 异步通信好,用户体验好
    2. 减少冗余请求,减轻了服务器负担,按需获取数据,节约带宽资源
    3. 基于标准化并被广泛支持的技术,不需要下载插件或者小程序
  • 缺点

    1. 存在一定的安全性问题,ajax暴露了与服务器交互的一些细节
    2. 对搜索引擎的支持比较弱
    3. 破坏了程序的异常机制
    4. 无法用URL直接访问
    5. ajax干掉了back按钮和加入收藏书签功能,即对浏览器后退机制的破坏。

new一个对象的过程中发生了什么

1. 创建一个空对象,将他的引用赋值给this,继承函数的原型。
2. 通过this将属性和方法添加至这个对象
3. 最后返回this指向的新对象,也就是实例

ECharts请求数据在什么时候

因为ECharts需要对DOM进行操作,所以会把数据请求放到mounted中。

浏览器市场占有率前三

Chrome占有率达到了61.55%,紧随其后的是Safarihe和Firefox。

目前较为主流的浏览器内核

  • Blink内核
  • Webkit内核
  • Gecko内核
  • Chromium(基于Webkit内核)
  • Trident内核
  • EdgeHTML内核(Trident分支)

说一下你对项目优化的理解

项目优化主要是由项目和代码两个方面进行优化。

页面级别的优化,比如减少 Http 请求次数、加快资源的加载速度,二是代码级别的优化,页面重新渲染一次会经过浏览器的重排(reflow)和重绘(repaint),这两部操作是非常耗时的

  • 代码优化
    • 使用异步组件
    • 减少冗余的代码
    • 封装可复用组件
  • 页面优化
    • 减少HTTP请求
    • 项目资源压缩
    • CSS Sprites(精灵图或者说雪碧图)
    • 合理利用缓存
    • vue路由懒加载

项目上线的流程

先是产品确定需求,然后开需求评审大会,需求通过后ui出效果图。如果是后台页面一般只有一个产品原型,测试写测试用例,前段开发页面后台写接口,页面跟接口开发完之后前后台联调就是所谓的调接口对key跟值。对完之后自测一边,流程能走通然后交给测试一测 ,测完然后该bug改完在测测完再改。

前端跨域问题解决

首先跨域问题是前后端交互一直存在的一个问题,它来源于浏览器的同源策略,开启跨域相对来说会比较安全,图片可以防盗链。跨域一般只在浏览器端存在,对于服务器端和iOS,Android等是没有跨域的。

​ 解决跨域的方式有很多种,比如说jsonp,前端代理,然后还有可以通过node写一个代理,还有CORS也就是全局资源共享。jsonp存在着诸多限制,比如只支持get请求什么的,然后CORS是后端来解决前端跨域问题的,前端遇到跨域问题一般都是会通过前端代理来实现跨域的。

​ 在开发vue项目的时候会配置一个vue.config文件,然后在文件内对项目做一些配置,比如说接口还有跨域问题。他的使用方法跟webpack是比较类似的,我们可以通过一个proxy对象来配置解决跨域问题。

什么是模块化开发

模块化开发就是在开发过程中,js文件按照功能区分,根据不同的需求引入不同的文件,源于服务器端。
在前端开打中,模块化的概念最早出现在node.js中,commne.js是node中最开始的模块化的概念。
es6提出了原生的模块化 import 和export。但是因为一些浏览器对es6的支持并不好,所以需要借助一些工具
一般我们会使用webpack模块化打包工具来实现

如何进行多人协同开发

使用git来实现多人协同开发

在多人协同开发过程中碰到提交冲突怎么解决

  • 在当前分支上找到冲突文件,然后直接修改代码(使用vim修改,cat查看冲突文件,注意要删除git自动生成的冲突代码分隔符),或者使用命令
  • 通过git stash命令,把工作区的修改提交到栈区,目的是保存工作区的修改;
  • 通过git pull命令,拉取远程分支上的代码并合并到本地分支,目的是消除冲突;
  • 通过git stash pop命令,把保存在栈区的修改部分合并到最新的工作空间中;

内存泄漏怎么解决

内存泄漏引起的原因一般是因为滥用闭包,解决办法是在退出函数之前将不使用的局部变量全部删除。

sessionStorage localStorage cookie的区别

  1. localStorage
    localStorage的生命周期是永久的,除非用户在浏览器提供的UI上清除localStorage信息,否则这些信息
    将永久存在,存放数据大小一般为5MB 而且它仅在客户端保存,不参与服务器通信
  2. sessionStorage
    sessionStorage仅在当前会话下有效,存放数据大小一般为5MB不参与服务器通信,原生接口可以接受
    也可以在此封装起来对object和array有更好的支持
    (只能保存字符串类型,复杂对象只能通过json的形式保存)
    (保存数据setItem,获取数据getItem,删除removeItem 删除所有clear)
    不同浏览器无法共享两种信息 相同浏览器不同页面可以共享localStorage 相同浏览器不同页面或者标签
    不能共享sessionStorage
    localStorage适用于保存长期数据 sessionStorage保存一次性的敏感数据
  3. cookie(HTTP Cookie)通过name=value的方式存储
    cookie的存储数据大小只有4kb左右,有个数限制,一般不能超过20个。生效时间默认是浏览器关闭失效
    ,但是可以自己设置,cookie会参与服务器端通信,每次都会携带在HTTP头中,如果保存过多会有性能
    问题。cookie也是不安全的,但是可以设置cookie的生命周期,使之不会永远有效。
    cookie的优点
    具有极高的扩展性和可用性。
    cookie的缺点
    长度和数量有限制,每一个域中最多只能保存20条,每个不能超过4kb,否则就会被拦截掉。
    如果cookie被拦截 那么就可以获取所有的session信息,加密也没用。

methods computed watch的区别

methods

中定义的是具体的方法,根据一些特定的触发条件,调用一次执行一次,比如说点击事件

computed

computed是vue中独有的计算属性,它是基于他们的依赖进行缓存的,只有依赖发生改变,才会重新计算
就算在data中没有直接声明出要计算的变量,也可以在computed中写入
计算属性默认只有getter 需要的时候可以自己设置setter方法 setter默认传递一个参数,这个参数就是当前对象

watch

watch的作用是监听一个值的变化,并调用因变化需要执行的方法。
它用于观察vue实例上的数据变动,对应一个对象,键是表达观察式,值是回调,也可以是方法名,或者一个对象。

数据量大,需要缓存使用computed,每次都需要加载不需要缓存使用methods
computed 和 watch 都可以观察页面的数据变化。computed的依赖是多个的,watch的依赖只能是单个的

vue 组件父子,子父,兄弟通信

父传子是通过import引入子组件,在components中注册 在子组件标签上用v-bind绑定要传递的数据,子组件通过props接收
并明确传递属性的数据类型

子传父通过提交一个$emit方法,这个方法接收两个参数,第一个是要派发的事件,第二个参数是要传递的参数
然后在组件标签上自定义事件接收这个提交的方法在methods中定义

兄弟组件传值有两种方法 一种通过event.bus中间件实现 在要传值的两个组件中分别引入eventbus.js然后提交的方法是bus.$emit
还有就是通过vuex

说一下你对vuex的理解

vuex是vue的一个状态管理器,然后vuex有几个属性。
分别是state,getters,mutations,actions,modules,plugins

state
state中定义并管理组件的数据,是组件数据的来源,state中数据的改变只能在vuex中
getters
gettes相当于vuex的计算属性,依赖的值发生变化就会重新计算
mutations
mutations中定义具体的方法,修改state中的数据状态,并且是同步的
在组件内通过this.$store.commit(“方法名”,message)提交方法,可以传递参数

actions
actions是异步的方法,在组件内通过this.$store.dispatch()提交
方法接收一个context参数,用来提交到mutations执行同步操作,可以进行数据的请求,比如json
modules
modules是store的子模块,是为了在实际开发中避免出现一个过于庞大的store,然后进行模块化管理,最终集合到一个store中
plugins
plugins是vue的插件,接收store作为唯一的参数,在插件中不能直接修改state,需要提交mutation

说一下你对vue路由的理解

Vue有一个完整的生命周期,从开始创建,初始化数据,编译模板,挂载dom,数据改变更新dom,最后再到销毁组件的过程,我们称之为vue的声明周期,通俗点来说就是vue实例从创建到销毁的过程。

vue生命周期分为四个阶段八个钩子函数

  1. beforeCreate 实例或组件通过new Vue()创建出来之后会初始化事件和生命周期,然后就 会执行beforeCreate钩子函数,这个时候数据还没有挂载,只有一些默认的生命周期钩 子和默认事件,无法访问数据和操作dom,一般不进行操作
  2. created data和methods都已经初始化完成,在这个时候已经可以使用,并修改数据, 在 这里更新不会触发更新阶段函数,一般在这个阶段做一些数据的初始化还有初始化 的页面请求,结束loading。
  3. beforeMount 执行在组件挂载之前,在该阶段没有渲染出HTML元素,data初始化完成,
    Ref仍然不可以操作。Render函数首次被调用。
    在这个阶段可以访问数据,虚拟dom已经存在。
    该阶段在服务端渲染期间不被调用。
  4. mounted 这个函数是在页面完成挂载之后执行的,这时el被this. e l 替 换 , 可 以 操 作 r e f 了 , 一 般 把 数 据 的 请 求 放 到 这 个 阶 段 , f i l t e r 也 是 在 这 个 阶 段 生 效 的 。 在 这 个 阶 段 可 以 操 作 真 实 d o m 等 。 M o u n t e d 不 会 保 证 所 有 的 子 组 件 也 都 一 起 被 挂 载 , 如 果 希 望 等 到 整 个 视 图 渲 染 完 毕 , 可 以 在 m o u n t e d 内 部 使 用 t h i s . el替换,可以操作ref 了, 一般把数据的请求放到这个阶段,filter也是在这个阶段生效的。在这个阶段 可以操作 真实dom等。 Mounted不会保证所有的子组件也都一起被挂载,如果希望等到整个视图渲染完毕, 可以在mounted内部使用this. elreffilterdomMountedmounted使this.nextTick。
    该阶段在服务端渲染期间不被调用。
  5. beforeUpdate 该函数在数据更新时调用,发生在虚拟DOM打补丁之前,在这里我们可以 讲更新前的数据保存起来等到更新后再使用。
    这里适合在更新前访问现有DOM,比如手动移除事件监听器。
    该阶段在服务端渲染期间不被调用,因为更新阶段不会在服务端进行。
  6. updated 由于数据更改导致虚拟DOm重新渲染,在这之后会调用这个钩子函数,在数据 更新之后做一些处理,也就是监控数据的变化。
    在大多数情况下都不应该在这个阶段更改状态,如果相应状态要发生改变可以使用计算 属性或者监听属性代替
    updated 不会保证所有的子组件也都一起被挂载,如果希望等到整个视图渲染完毕, 可以在updated 内部使用this.$nextTick。
    该阶段在服务端渲染期间不被调用。
  7. beforeDestory 在实例销毁之前调用,在这个阶段实例仍然完全可用,可以做一些清除定时 器的操作
    该阶段在服务端渲染期间不被调用
  8. destoryed
    在组件销毁的时候执行,也就是在销毁之后调用,在这个ref不存在了。
    这个阶段调用后,对应的实例所有指令都被解绑,所有的事件监听器被移除,所有的子 实例也都被销毁
    该阶段在服务端渲染期间不被调用

Vue生命周期有多个事件钩子,让我们在控制整个vue实例的过程中更容易形成好的逻辑,而且给了我们在不同阶段添加自己代码的机会。

vue获取数据在哪个周期函数?

看情况而定,创建完成后到挂载结束后的三个钩子内都可以获取,一般在created里面是最好的,如果需要进行dom操作的话就用mounted。
因为在created阶段html并没有被渲染出来,在这个阶段获取数据是改变不了dom元素的。
而mounted因为已经渲染完成了,所以可以对dom进行操作。
Vue一般不推荐对dom进行操作,所以还是在创建完成后created阶段请求比较好。

你可能感兴趣的:(面试题)