前端八股文经验分享:面试拷打经历 与 知识总结(纯个人总结)(一) - 持续更新ing

一个面试面麻的人,在这里我把总结的所有面经分享给大家,希望大家能找到理想的工作。

我总结的面经内容囊括了自己面试题/笔试题,掘金、牛客、小红书、博客其他同学分享的内容,内容量很大,我会尽快更新的。都是个人总结的白话文描述,如有问题 欢迎指正。


1. 数组扁平化的方法

Ex. var arr=[1,[2,[3,[4,5]]]];  =>  arr=[1,2,3,4,5]

  1. 传统方法 递归
  2. 使用reduce函数递归遍历
  3. 数组强制类型转换
    对于数组对象,toString方法连接数组并返回一个字符串,其中包含用逗号分隔的每个数组元素。返回的字符串使用split分割成子字符串数组,最后将数组中每个元素的类型转换为Number
  4. 使用ES6的flat方法 flat(depth)
  5. 使用JSON的函数和正则表达式
    使用JSON的序列化函数stringify()先对数组进行序列化,再用正则去掉[],得到的结果在最外层加上[]后使用JSON.parse()恢复成数组对象。
  6. 扩展运算符与some函数结合
    先用some方法把数组中仍然是数组的项过滤出来,再执行concat操作,利用ES6的扩展运算符 ‘ ... ' 将其拼接到原数组中,最后返回。

2. CSS两列布局的实现方式

(1)float+calc() : 左列开启浮动+右列开启浮动+右列宽度为父级100%减去左列宽

(2)float+margin-left :左列开启浮动+右列增加外边距

(3)absolute+margin-left :开启定位脱离文档流+(同上)

(4)float+overflow : {overflow:hidden}

(5)flex布局:.container {display:flex}       

                          .right {flex:1}

(6)grid布局

3. BFC

一、什么是BFC? 

        一个块格式化上下文(block formating context)是Web页面得可视化CSS渲染出得一部分,它是块级盒布局出现的区域,也是浮动元素进行交互的区域

二、触发条件

  1. 浮动元素,float不是none
  2. 绝对定位元素元素具有position为absolute或fixed
  3. 内联块,元素具有display:inline-block
  4. 表格单元格,元素具有display:table-cell
  5. 表格标题,元素具有display:table-caption
  6. 具有overflow且值不是visible的块元素
  7. display:flow-root
  8. column-span:all 应当总是会创建一个格式化上下文,即便具有column-span:all 的元素并不被包裹在一个多列容器中

三、BFC特性

  1. 内部的Box会在垂直方向上一个接一个的放置
  2. 垂直方向上的距离由margin决定
  3. BFC的区域不会与float的元素区域重叠
  4. 计算BFC的高度时,浮动元素也参与计算
  5. BFC就是页面上的一个独立容器,容器里面的子元素不会影响外面元素

四、为什么要使用BFC

  1. BFC可以解决子元素浮动导致父元素高度塌陷的问题
  2. BFC可以解决两个兄弟盒子之间的垂直距离是由他们的外边距所决定的,以较大为准
  3. 不被浮动元素覆盖
  4. 防止文字环绕

4. 水平居中方式

1、margin:auto; 元素有宽度有高度时

2.、position:absolute; 元素有宽度有高度时,设置position和margin为负的宽高的一半

                                   元素有宽度有高度时,利用calc计算top和left

                               元素宽度、高度未知时,设置position和transform:translate(-50%, -50%)

3、弹性盒子:为其父元素设置display:flex

4、利用水平对齐和行高:设置text-align和line-height,实现单行文本水平垂直居中

5、grid:在网格项目中设置justify-self, align-self 或者 margin:auto

                在网格容器上设置justify, align-items或者jsutify-content, align-content

5. Vue-Router的原理,两种模式

一、hash模式——即地址栏URL中的 # 符号

  1. hash不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash不会重载页面
  2. 404错误:仅hash符号之前的内容会被包含在请求中,即使没有做到对路由的全覆盖也不会返回404错误
  3. hash的原理是采用hashchange事件,可以在window监听hash的变化,我们在url后面随便添加一个 #xx 触发这个事件

二、history模式

  1. 需要特定浏览器支持,有back,forward,go,pushState等方法,提供了对历史记录修改的功能,当它们执行时,虽然改变了当前url,但浏览器不会立即向后端发送请求
  2. 404错误:前后端发起请求的url需一致,返回404错误
  3. histor的原理是H5的几个新API

6. 全局路由守卫和组件路由守卫

一、全局守卫

  1. 全局前置守卫 beforeEach
    router.beforeEach((to, from, next) => {
    })
    在路由跳转之前被触发
  2. 全局解析守卫 beforeResolve
    参数: to, from, next
    在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
  3. 全局后置钩子 afterEach
    参数:to, from, failure

二、组件内路由守卫

  1. beforeRouteEnter: 不能访问this,因为守卫在导航确认之前被使用,因此即将登场的新组件还没被创建
  2. beforeRouteUpdate: 主要是路由复用时被调用,即在当前页面跳转,会走该路由,而不会重头
  3. beforeRouteLeave: 这个离开路由守卫通常用来禁止客户在未保存修改前突然离开,该导航可以通过next(false)来取消

注意:beforeRouteEnter是支持给next传递回调的唯一守卫,对于beforeRouteUpdate和beforeRouteLeave来说,this已经可用了,所以不支持传递回调,因为没有必要了。

7. some和every方法的区别

相同点:

  1. 都可以遍历数组每一项数据
  2. 都不会对空数组进行检测
  3. 都不会改变原始数组

不同点:

  1. some() 方法会依次执行数组的每个元素
    如果有一个元素满足条件,则表达式返回true,剩余的元素不会再执行检测
    如果没有符合条件的元素,则返回false
  2. every() 方法使用指定函数检测数组中的所有元素
    如果数组中检测到有一个元素不满足,则整个表达式返回false,且剩余的元素不会再进行检测
    如果所有元素都满足条件,则返回false

8. forEach 和 map 的区别

相同点:

  1. 都是循环遍历数组中的每一项
  2. 每次执行匿名函数都支持三个参数,参数分别为item(当前每一项), index(索引值), arr(原数组)
  3. 匿名函数的this都指向window
  4. 只能遍历数组

不同点:

  1. map() 方法会得到一个新数组并返回;forEach() 会修改原来的数组
  2. forEach() 允许callback 更改原始数组的元素;map() 返回新的数组

使用场景:

1、forEach() 适合你并不打算改变数据的时候,而只是想用数据做一些事情——比如,存入数据库或打印
2、map() 适合你要改变数据值的时候,不仅在于它更快,而是返回一个新数组,可以搭配filter(), reduce() 等

9. 浅拷贝 和 深拷贝

一、浅拷贝——拷贝深度不够会改变原数组
push、pop、unshift、shift、reverse、sort、forEach、Object.assign(第一个参数是拷贝的目标对象,后面的参数是开呗的来源对象)、扩展运算符
 

二、深拷贝——不会改变原数组,增加了一个新指针并申请了一个新元素地址
slice、concat、map、filter、reduce、for...in...、使用JSON.parse和JSON.stringify

注意:基本类型(string, number, boolean, null, undefined, symbol)不存在深浅拷贝问题,因为赋值的是数据;引用类型(Object, Array, Date, RegExp, Function)存在这个问题

10. reduce 方法

定义:reduce() 方法接收一个函数作为累加器,数组中的每个值(从左至右)开始缩减,最终计算为一个值
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

reduce的常用方法:1)数组求和
                                 2)累加数组中对象的值
                                 3)计算数组中每个元素出现的次数
                                 4)数组去重
                                 5)二维数组变一维
                                 6)将多维数组变一维
                                 7)根据属性把对象分类

11. 事件循环机制

浏览器时间循环 和 node.js事件循环

Event Loop:同步任务+异步任务

所有同步任务都在主线程上执行,形成一个函数调用栈(执行栈),而异步任务则先放到任务队列里,任务队列又分为宏任务和微任务。

宏任务:script(整块代码)、setTimeout、setInterval、I/O,UI交互事件、setImmediate(node环境)
微任务:new promise().then 回调、MutationObserver(h5新特性)、process.nextTick(node环境)        

12. 闭包

定义:有权访问其他函数作用域中变量得函数

JS中,变量得作用域属于函数作用域,在函数执行完毕后,它得作用域会被销毁,内传也会被回收,但由于闭包在函数内部创建一个子函数,且子函数可以访问父级函数中得作用域,即父函数执行完作用域也不会被回收,这就是闭包。

缺点:比普通函数更见占用内存,可能会造成内存泄漏

13. 箭头函数

语法比函数表达式更加简洁,并且没有this, arguments, super 或 new.target;更加适用于本来需要隐匿函数的地方,并且它不能用作构造函数。

14. this指向

  1. 在普通函数中,this指向window
  2. 在构造函数中,this指向创建对象
  3. 在方法声明中,this指向调用者
  4. 在定时器中,this指向window
  5. 在事件中,this指向事件源

15. 作用域有哪些

全局作用域        函数(局部)作用域        块级作用域        静态作用域        动态作用域

16. JS获取DOM节点的方式

getElementById        getElementByClassName        getElementByTagName

querySelector & querySelectorAll                              getElementByName

document.title & document.body

17. CSS布局

静态布局        自适应布局        流式布局        响应式布局        弹性布局

18. 双向绑定的原理

通过数据劫持结合发布订阅模式的方法来实现

19. Vue2 和 Vue3 的区别

一、Composition API
        Vue2是选择式API;Vue3是组合式API

二、双向数据绑定原理的变化

        Vue2利用数据劫持结合订阅发布 Object.defineProperty();Vue3使用ES6的Proxy API对数据代理

三、Vue3支持碎片

四、建立数据
        Vue2放入data;Vue3需使用setup(),在组件初始化构造的时候触发

五、生命周期钩子不同

六、父子传参不同

七、Vue3新增Teleport瞬移组件

20. HTTP 和 HTTPS 的区别

  1. https需要到ca申请证书,一般免费证书较少,需要一定费用
  2. http是超文本文本传输协议,信息是明文,https是具有安全性的ssl加密传输协议
  3. 连接方式不同,用的端口不一样,前者是80,后者是443
  4. http的链接是无状态的;https协议是有ssl+http协议构建的可进行加密传输,身份认证的网络协议

21. 用elementUI的时候,如果需要el-button,打包的时候怎么按需打包

按需引入,借助babel-plugin-component打包

22. tree shaking(摇树优化)

ES6推出tree shaking,当我们在项目中引入其他模块时,它会自动将我们用不到的代码,或者永远不会执行的代码摇掉,在Uglify阶段查出,不打包到bundle中。

23. 为什么组件库按需加载时使用babel插件实现而不是依赖tree-shaking

tree-shaking依赖ES module语法,webpack不支持导出ES module。

组件库都是用webpack开发,不支持ES module导出

24. 浏览器渲染页面的过程

  1. 渲染引擎首先通过网络获得请求文档的内容
  2. 解析HTML文件,构建DOM Tree
  3. 解析CSS,构建CSSOM Tree(CSS规则树)
  4. 将DOM Tree 和 CSSOM Tree合并,构建Render Tree(渲染树)
  5. reflow(重排):根据Render Tree进行节点信息计算(Layout)
  6. repaint(重绘):根据计算好的信息绘制整个页面(Painting)

25. JS 和 CSS 会不会阻塞页面渲染

  1. 通过style标签引入的样式和同步加载的link标签会阻塞页面渲染,但异步加载的link标签则不会
  2. js脚本通过添加async或defer的方法来开启异步下载,开启异步下载则不会阻塞页面渲染,但下载完成后,加async的脚本会立即执行,执行时会阻塞页面渲染;
    而加defer的脚本会等样式dom结构加载完成后才会执行,此时页面已经渲染完了,所以只有同步脚本和个别情况下加了async的脚本会阻塞渲染

26. 手写防抖和节流

防抖
function debounce(fn,wait){
    let timer = null;
    return function(){
        if (timer) {
            clearTimeout(timer)
            timer = null
        }
        timer = setTimeout(()=>{
            fn.call(this, arguments)
        },  wait)
    }
}

节流

function throttle(fn, wait){
    let timer = null
    return function(){
        if(!timer){
            timer = setTimeout(()=>{
                fn.call(this,arguments)
                tiemr = null
            }, wait)
        }
    }
}

27. 三次握手,四次挥手

三次握手:指建立一个TCP连接时,需要客户端和服务端总共发送3个包,以确认双方的接受能力和发送能力是否正常,为后面的可靠性传送做准备

四次挥手:终止TCP链接只需要发送4个包,客户端或服务端均可主动发起挥手动作

28. 状态码

  • 1XX (信息性状态码)                        表示接受的请求正在处理
  • 2XX (成功性状态码)                        表示请求正常处理完毕
  • 3XX (重定向状态码)                        表示需要附加操作以完成请求
  • 4XX (客户端错误状态码)                 表示服务器无法处理请求
  • 5XX (服务端错误状态码)                 表示服务器处理请求出错

29. 手写对象扁平化

const flatten = (arr) => {
    return arr.reduce((pre, cur) => {
            return pre.concat(Array.isArray(cur)? flatten(cur) : (cur)
      }, [])
}

30. setTimeout 实现 setInterval

setTimeout(function f() {
    setTimeout(f,interval); 
}, interval)

31.  水平垂直居中方法

  1. flex布局,父元素:display:flex; justify-content: center; align-items: center;
  2. 子绝父相,子元素:left:50%; top:50%; transform: translate(-50%, -50%)
  3. 子绝父相,子元素:left:0; top:0; botton:0; right:0; margin: auto
  4. 文字的话,text-align:center; line-height 和 height 相等

32. Promise.allSettled()

用来确认一组异步操作是否全都结束了,包含了“fulfilled” 和 “rejected” 两种情况
Promise.allSettled() 方法接受一个数组作为参数,数组每个成员都是一个Promise对象,并返回一个新Promise对象,只有等到参数数组的所有Promise对象都发生状态变更(不管是fulfilled还是rejected),返回的Promise对象才会发生状态变更

33. 盒子模型分哪两种

  1. W3C标准的盒子模型(标准盒模型)
  2. IE标准的盒子模型(怪异盒模型)

34. 输入url后会发生什么

  1. 浏览器向DNS服务器请求解析该URL中的域名所对应的IP地址
  2. 解析出IP地址后,根据该IP地址和默认端口80,和服务器建立TCP连接
  3. 浏览器发出读取文件(URL域名后面部分对应的文件)的HTTP请求,该请求报文作为TCP三次握手的第三个报文的数据发送给服务器
  4. 服务器请求作出回应,并把对应的html文本发送给浏览器
  5. 释放TCP连接
  6. 浏览器将该html文本显示内容

35. 手写ajax(使用promise封装)

function getJSON(url) {
  let promise = new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.onreadystatechange = function () {
      if (this.readyState !== 4) return;
      if (this.status === 200) {
        resolve(new Error(this.statusText));
      } else {
        reject(new Error(this.statusTzext));
      }
    };
    xhr.onerror = function () {
      reject(new Error(this.statusText));
    };
    xhr.responseType = 'json';
    xhr.setRequestHeader('Accept', 'application/json');
    xhr.send(null);
  });
  return promise;
}

36. 前端有什么安全性问题 

  1. XXS攻击(跨站脚本攻击)
  2. CSRF安全漏洞(跨站请求伪造)
  3. 文件上传漏洞
  4. 限制URL访问,越权访问
  5. 不安全的加密存储
  6. SQL注入攻击
  7. OS命令注入攻击

37. 面向对象的继承方法

  1. 原型对象
  2. 原型链继承
  3. 空函数作为中介继承
  4. 绑定继承
  5. 组合继承
  6. 拷贝继承
  7. ES6的class继承

38. 手写一个组合继承

function superType() {}
function subType() {
  //构造函数继承
  superType.call(this, ...arguments);
}
//原型链继承
subType.prototype = new superType();
//对象增强
subType.prototype.constructor = subType();

39. defer 和 async 的区别 

一、
        有async,加载和渲染后续文档元素的过程将和script.js的加载与执行异步

二、

        有defer,加载后续文档元素的过程将和script.js的加载异步,但是script.js的执行要在所有元素解析完成之后,DOMContentLoaded事件触发之前完成

40. 工厂模式的理解

工厂模式:主要是用来实例化有共同接口的类,它可以动态的决定应该实例化哪一类
主要分为三种形态:简单工厂模式、工厂方法模式、抽象工厂模式

一、简单工厂模式
        主要有一个静态方法,用来接收参数,并根据参数进行switch或if判断来决定返回实现同一接口的不同类的实现

二、工厂方法模式

        把工厂类定义为接口,以多态的形式来削弱工厂类的职能,对简单工厂进一步的解耦,降低简单工厂模式的风险,提高可维护性,可扩展性

三、抽象工厂模式

        工厂模式下一个工厂只能生产同类同品 的产品,而抽象工厂模式下一个工厂可以生产多类同品 的产品

41. $nextTick 的使用场景

  1. 在vue生命周期的created()里进行DOM的操作一定要使用nextTick(),因为created执行的时候DOM还未渲染
  2. 在方法里操作DOM,由于dom元素还没有更新,因此打印出来的还是为改变之前的值,而通过this.$nextTick()获取到的值为dom更新之后的值

42. Vue2 数据发生变化到页面变化的基本流程

  1. 先将数据进行Obj.defineProperty() 进行绑定,判断数据为数组或者对象进行绑定
  2. 当页面开始渲染会定义updateComponent方法,这个方法主要就是为了调用render方法
  3. 进入render的时候会执行页面使用的值,这时候会触发该数据的get属性
  4. 开始进行绑定依赖
  5. 之后通过patch方法将节点进行更新替换或者新增
  6. 如果数据发生变化,会执行数据的set方法,这时数据的Dep.notify会调用
  7. Dep.notify会去调用绑定的Watcher,促使它更新,并收集所有改变,一次性进行改变
  8. 调用Watcher的run()方法,run方法会调用updateComponent方法进行render更新

43. vue中v-for如何实现对数组、对象、数字的遍历

数组:v-for="(item, index) in/of arr"
对象:v-for="(value, index) in obj“
数字:v-for="(item,index) in 数字"         index从1开始

44. 哪些因素会影响重排重绘

  1. 页面首次进入渲染
  2. 浏览器resize
  3. 元素位置和尺寸发生改变
  4. 可见元素的增删
  5. 内容发生改变
  6. 字体font改变
  7. CSS伪类激活

45. GET 和 POST 的区别

get参数在请求地址 post参数在请求体

get有长度限制

post没有长度限制
get有缓存 /
get返回的结果不会变 post结果可能不一样

46. HTTP请求的几种类型

GET、POST、OPTIONS、PUT、DELETE、HEAD

47. HTTP缓存的方式

一、强制缓存

        指只要浏览器缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的主动性在于浏览器这边

二、协商缓存

        与服务端协商之后,通过协商结果来判断是否使用本地缓存

48. 浏览器的存储方式

1)属于文档对象模型:documentcookie
2)属于浏览器对象模型:localStroage、sessionStorage,indexDB


区别:

  1. cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据传给服务器,仅在本地缓存
  2. 存储大小限制不同,cookie数据不能超过4K,同时每次http请求都会携带cookie,所以cookie只适合保存很小的数据。
    sessionStorage和localStorage虽然也有存储大小限制,但比cookie大很多,可以达到5MB或更大
  3. 数据有效期不同:
    sessionStorage 仅在当前浏览器窗口关闭前有效
    localStorage 始终有效,窗口或浏览器关闭也一直保保存,因此用作持久数据
    cookie 只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
  4. 作用域不同:
    sessionStorage 不在不同的浏览器页面中共享,即使同一个页面
    localStorage 在所有同源页面窗口中都是共享的
    cookie 在所有同源页面窗口中都是共享的
                                   

49. transform、transition、translate、animation的区别

  • transition、transform、animation这三个是CSS属性,而translate是2D转换的一种方法,是transform的一个属性值
  • transform是2D、3D变换的属性,只是动画可用的一种属性,因为使用transform不会引起页面的重排
  • transition、animation才是动画中必备的两个属性

50. CSS画三角形

div {
        border-left:50px solid transparent;
        border-right:50px solid transparent;
        border-bottom:50px solid #333;
        width:0;
        height:0;
    }

你可能感兴趣的:(面试,经验分享,javascript,react.js,vue.js,typescript,es6)