面试题

275 阅读9分钟

documentFragment

  1. 左侧固定宽度,右侧自适应
  • flex布局
  • 左侧浮动,右侧设置宽度100%
  • 左侧dispay:inline-block,右侧float:right 宽度用calc计算
  • grid
  1. 微前端如何去控制权限?
  2. 数组的去重
  • Array.form + new Set
  • 假设原数组是A,创建一个空数组B,遍历A数组把元素放进B中,用includs或者findIndex判断,如果B中已经有了就不用放了
  • filter + indexOf (indexOf默认返回数组中第一个满足条件的元素的索引)
  1. 组件通信方式
父子组件通信:
$ref prop $emit eventBus vuex $attrs $listeners $parent provide inject $children v-model.sync 插槽
隔代通信:eventBust vuex provide inject $attrs $listeners
兄弟通信:vuex eventbus
  1. computed watch computed: 一个属性值依赖其他属性的时候,具有缓存性 watch: 需要在属性变化的时候进行某些操作

  2. data为什么是函数 组件可能会被创建多次,如果data是一个对象的话,那所有实例之间就会共享一个对象。但是data为函数的时候,每创建一个实例,都会去调用data函数,返回原始数据的副本,组件实例之间的数据互不干扰。

  3. 值和引用存放在哪 值:栈 引用:变量存放在栈中,指向堆内存

  4. 为什么会有虚拟dom 虚拟dom就是一个js对象

  5. 组件开发需要考虑什么 高内聚 低耦合

  6. 数组的监听和对象的监听有什么区别 数组不需要深度监听

  7. watch能不能监听路由 $route

  8. xss和csrf攻击

xss(跨站脚本攻击): 通过在网页注入恶意的代码并且成功被浏览器执行,可以对网页进行控制或者获取用户隐私。 防止xss攻击:转义和过滤(<>,alert,$等),httpOnly: 虽然不能直接防范劫持和篡改,但是能够防止js直接读取身份类的信息,比如cookie

csrf(跨站请求伪造):攻击者盗用受害者的身份,以受害者的名义发送请求,这样就能够在未授权的条件下执行一些需要权限才能做的事情。 防止csrf攻击:同源验证,token验证,csrfKey(cookie的一部分)

  1. 跨域

协议、域名、端口有一个不一致时,会发生跨域

  • proxy代理,在vue.config.js中设置目标地址

  • jsonp实现(需要前端和后端相互配合)

    script标签没有同源限制, 前端动态的创建script标签,src中传入要请求的地址,然后在请求的query参数 中传入callback参数,参数值为当前文件中的一个全局函数。服务器收到请求后,会返回一个数据,这个时候浏览器会去执行query参数中的全局函数,这时就可以拿到服务器的数据了。
    jsonp只能处理get请求
  • cors实现(服务端实现)
客户端发起请求
服务器端设置相关的头信息:
access-control-allow-origin
access-control-allow-headers
access-control-allow-methods
  • http proxy (webpack-dev-server) (前端处理)
devServer: 设置proxy代理,changeOrigin: true
  • nginx代理 (前端不需要处理)
  • postmessage
  • websocket (前端处理)
  • document.domain + iframe (同一个主域,不同子域)
v.qq.com
m.qq.com
  • window.name + iframe
  1. data为什么是函数

这样每个实例可以维护一份被返回的对象的拷贝。多个实例之间的数据也不会相互影响。

  1. 事件委托 利用事件冒泡的原理,通过在父级元素上设置事件监听函数来监听子元素上面事件的触发。 比如需要在li元素上绑定事件时,为了避免多次绑定,可以在ul元素上设置事件监听。

  2. webpack

  3. cookie 和 session

  • 为什么会有cookie和session? http是无状态的,也就是服务器不能知道浏览器的历史请求记录,session和cookie其实是对无状态请求的一个弥补。

  • 什么是cookie和session? cookie是服务端发送给客户端的数据,并且会在浏览器再次请求服务器的时把cookie发送给服务端,它存储在客户端。

session代表客户端和服务器之间的一次会话,在同一个应用切换页面时session不会失效,只有当会话关闭或者session超时才会失效。

  • cookie和session之间怎么配合?

在浏览器第一次请求服务器的时候,服务器会创建一个当前用户的session信息,并把session中的sessionId传给客户端,客户端接收到之后会把sessionId存储在cookie中,并且记录这个sessionId所在的域名。

浏览器再次请求服务器的时候会把cookie发送给服务器,服务器从中获取sessinId,在根据sessionId去查找对应的session信息,如果没有,则说明当前用户没有登录或者登录失效。如果有说明已经登录了可以进行后续操作。

  • 对比: cookie存储在客户端,session存储在服务端 cookie存储量最大只有4k,session存储量远大于cookie cookie只能存储ASCII码,session可以存储任意类型的数据 cookie存储在客户端,容易被非法获取,session存储在服务端,更安全一些
  1. SPA(单页面应用)

一个项目只有一个页面,页面加载完成后,页面不会因为用户的操作而重新加载页面或者使跳转,而是利用js动态的变换html来模拟视图之间的跳转。所以单页面应用的url不会发生改变。 会产生两个问题:1. 用户进行后退刷新或者前进时,无法获得期望的视图。2. url不变,不利于搜索引擎进行收录。

hash: #后的hash值变化,不会触发请求。 hashChange实现无刷新跳转。 history: pushState和replaceState可以做到改变url,但不发送请求。参数(state,title,url) onPopState 当浏览器前进后退时,会触发

用户在刷新浏览器时,会重新加载不存在的路由码? 会 跟服务端做好协商,服务端对于未配置的路由都指向跟路径。

  1. 水平垂直居中

github.com/febobo/web-…

父元素 display: table-cell;vertical-align: middle; text-align: center; 子元素:display: inline 或者 display: inline-block

父元素:display: flex; align-items: center; justify-content: center;

父元素:display: grid;align-items: center; justify-content: center;

父元素:position: relative; 子元素:position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)

  1. 子元素定宽 父元素:position: relative 子元素:position: absolute; left: 50%; margin-left: 负自身的一半; top: 50%; margin-top: 负自身高度的一半

flex,grid,table-cell方式均可设置内联元素和块级元素的水平垂直居中

内联元素:

水平居中:text-align:center;
垂直居中:line-height: 父级元素高度

块级元素:

水平居中: margin: 0 auto;
或者 父级:position: relative; 子级: position: absolute; left: 50%; margin-left: 负自身的一半

垂直居中: 取5种水平垂直居中方法中的任意一种都可以

  1. 进程和线程

  2. ==和=== == 会对左右两边的值进行类型转换,js规范中规定null和undefined都为空值 undefined==null //true ===是严格相等,类型不同即为false

  3. 对象和函数的区别

  4. 闭包

有权访问另一个函数作用域中变量的函数

为什么会内存泄漏?

因为当外层函数执行完毕后,外层函数执行环境的作用域链会销毁,但此时内部函数还在引用外层函数的活动对象,这个活动对象会留在内存中。 解决办法:执行外层函数的时候会分配一块堆内存,把堆内存中的值置为null就行了

  1. 垃圾回收机制

  2. 浏览器兼容性问题

  3. 表单校验问题 锡安平台的旧版本基于angular开发的,在对表单进行必填校验时,发现火狐浏览器对于文档中不存在的表单也会去校验,导致无法提交表单

原因:ng-verify内部通过监听domNodeRemovedFromDocument事件去判断哪些表单项被移除了,移除了的表单项就不做校验。但通过查看canIuse发现,这个变异事件不支持火狐浏览器,于是就用MutationObserver去替代这部分逻辑,通过mutationObserver的observe方法可以知道哪些元素被移除了,进而只对存在的dom元素做表单校验。

  1. 使用mavon-editor富文本编辑成功之后回显文件名称,点击文件名称可以下载文件。 这个时候使用事件代理,在这个组件上设值监听函数,用addEventListener监听文件名称上的dom类型,如果是a标签则调用下载接口。 但是出现问题了,ie浏览器不支持addEventListner事件,所以增加了attachEvent事件去支持ie浏览器上面的这个功能

  2. watch和computed的区别

  3. 如何处理401页面?

用户登录成功后,会返回一个token和refresh_token 前端请求接口api --> 返回401错误 --> 前端判断是否有refresh_token -->如果有就用refresh_token请求新的token --> 后台成功返回一个新的token给我们 --> 更新vuex+本地存储持久化 --> 然后重新发送请求 --> 带上新的token请求数据 如果没有token就直接重定向到登录页

  1. 请求拦截和响应拦截
  • 请求拦截器
    1. 在请求发送前进行必要操作处理,例如设置请求头等,相当于是对每个接口里相同操作的一个封装;
    2. 利用nprogress插件实现接口请求的进度的进度条表示:请求拦截中开启nprogress,在响应拦截中关闭nprogress
  • 响应拦截器
    同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理(比如对响应进行统一的格式转换)等,也常来判断登录失效(状态码是401时置空token,跳转到登录页面),全局的提示等。 juejin.cn/post/710047…
  1. style中引入外部样式时,可能会污染全局样式,怎么去解决? 原因:
  • @import并不是引入代码到里面,而是发起新的请求获得样式资源,并且没有加scoped
  • 因此采用@import的方法引入外部样式时的作用域是全局

解决:利用style标签的src属性,把样式文件的路径赋给这个属性

  1. vue2和vue3的区别
  2. 首屏加载优化
  3. promise的.then是怎么执行的,怎么进行链式调用的
  4. 简单请求和复杂请求
  5. css3新增特性,h5新增特性
  6. ES6新特性
  7. 接口请求做进度条
  8. 组件怎么进行封装
  9. promise怎么进行.then的
  10. 路由模式
  11. rem和em
  12. vue的v-model原理
  13. 性能优化点
  14. SSR
  15. 路由守卫
  16. keep-alive生命周期
  17. 伪元素伪类
  18. 样式污染