Web前端面试题(持续更新中)

发布于:2024-05-01 ⋅ 阅读:(28) ⋅ 点赞:(0)

一、闭包是什么

JS中内层函数可以访问外层函数的变量,使内部私有变量不受外界干扰,起到保护和保存的作用,我们把这个特性称作闭包。

好处:

隔离作用域,保护私有变量;有了闭包才有局部变量,要不然都是全局变量了。

让我们可以使用回调,操作其他函数内部;

变量长期驻扎在内存中,不会被内存回收机制回收,即延长变量的生命周期;

        坏处:内层函数引用外层函数变量,内层函数占用内存。如果不释放内存,过多时,易引起内存泄露。

        引用场景: for循环中的保留i的操作 / 防抖和节流

二、内存泄露、垃圾回收机制 

内存泄露:

        是指不再用的内存没有被及时释放出来,导致该段内存无法被使用就是内存泄漏,内存泄漏指我们无法在通过js访问某个对象,而垃圾回收机制却认为该对象还在被引用,因此垃圾回收机制不会释放该对象,导致该块内存永远无法释放,积少成多,系统会越来越卡以至于崩溃

垃圾回收机制:

        就是垃圾收集器按照固定的时间间隔,周期性地寻找那些不再使用的变量,然后将其清楚或释放内存。(标记清除/引用计数)

三、浅拷贝与深拷贝 

        浅拷贝:将原对象或原数组的引用直接赋给新对象,新数组,新对象只是对原对象的一个引用,而不复制对象本身,新旧对象还是共享同一块内存。(拓展运算符。。。)

        深拷贝:开辟一个新的栈,两个对象的属性完全相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。(JSON.stringify和JSON.parse / 递归/Object.assgin )

        优点:方便,将字符串parse后创建新对象(新地址)

        缺点:如果被拷贝的对象中某个属性的值为undefined,则拷贝之后该属性会丢失,如果被拷贝的对象中有正则表达式,则拷贝之后的对象正则表达式会变成Object

四、route和router的区别详解 

 router是用来操作路由的

 route是用来获取路由信息的。 $route.path $route.params route.query等 

五、如何改变this指向(call、apply与bind区别) 

    call、bind、apply 都是 JavaScript 中用于改变函数执行上下文(即 this 指向)的方法。

    传参 call、bind可以传递无数个参数,apply只有两个参数,第二个参数为数组返回 call和apply方法是直接调用函数并改变函数上下文,而bind方法则是返回一个新函数,稍后调用时绑定指定的上下文。

六、箭头函数和普通函数的区别 

箭头函数是普通函数的简写,但是它不具备很多普通函数的特性this指向问题,箭头函数的this指向它定义时所在的对象,而不是调用时所在的对象没有arguments对象,不能使用arguments不会进行函数提升,不能new

七、浏览器存储,他们的区别? 

localStorage:永久保存,以键值对保存,存储空间5M

sessionStorage:关闭页签/浏览器时清空

cookie:随着请求发送,通过设置过期时间删除

session:保存在服务端

(localStorage/sessionStorage是window的属性,cookie是document的方法)

八、常用的数组方法有哪些? 

改变原数组:push、pop、shift、unshift、sort、splice、reverse

不改变原属组:concat、join、map、forEach、filter、slice

(slice切片的意思,根据传入的起始和终止下标,获取该范围数组。splice可根据传入参数个数不同实现删除、插入操作,直接操作原数组。第1个参数为起始下标,第2个为删除个数,第3个为要增加的数据)

九、Vue的生命周期 

beforeCreate:会在实例初始化完成、props 解析之后、data() 和 computed 等选项处理之前立即调用。此时不能获得DOM节点

created:在这个阶段vue实例已经创建,以下内容已经设置完成:响应式数据、计算属性、方法和侦听器。然而,此时挂载阶段还未开始,因此 $el 属性仍不可用。仍然不能获取DOM元素。

beforeMount:在组件内容被渲染到页面之前自动执行的函数,组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点。

mounted:在组件被渲染之后自动执行的函数。一般我们的异步请求都写在这里。在这个阶段,数据和DOM都已被渲染出来。

beforeUpdate:数据变化的时候自动执行的函数,此时变化后的数据还未渲染到页面之上。.

updated:数据变化之后自动执行的函数,此时变化后的数据已经渲染到页面之上

beforeDestroy:当 Vue 应用被销毁时,自动执行的函数。

destroyed当 Vue 应用被销毁后,且 dom 完全销毁之后,自动执行的函数。

十、Vue的Key的作用 

key主要用在虚拟Dom算法中,每个虚拟节点VNode有一个唯一标识Key,通过对比新旧节点的key来判断节点是否改变,用key就可以大大提高渲染效率 

十一、diff算法 

diff算法是指对新旧虚拟节点进行对比,并返回一个patch对象,用来存储两个节点不同的地方,最后利用patch记录的消息局部更新DOM 

十二、虚拟DOM的优缺点 

优点:减少了dom操作,减少了回流与重绘 

缺点:首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢

十三、回流和重绘 

render树中一部分或全部元素需要改变尺寸、布局、或着需要隐藏而需要重新构建,这个过程叫做回流,回流必将引起重绘 

十四、为什么避免 v-if 和 v-for 用在一起 

当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中,带来性能方面的浪费。 

十五、什么是Promise 

Promise异步编程的一种解决方案。Promise是一个构造函数,接收一个函数作为参数,返回一个 Promise 实例。

Promise对象有三种状态,他们分别是 pending(等待中) resolved(已完成)rejected(拒绝)

Promise.all哪怕一个请求失败了也能得到其余正确的请求结果的解决方案

promise 的then会返回一个新的 promise 对象,能保证 then 方 可以进行链式调用

十六、async、await 

Async 和 await 是一种同步的写法,但还是异步的操作,两个必须配合一起使用 

十七、宏任务和微任务有哪些?执行顺序 

宏任务:script,setTimeout,setInterval。

微任务:Promise,process.nextTick。

微任务会优先于宏任务执行。这意味着在当前任务执行结束后,所有微任务都会被立即执行,而宏任务只有在所有微任务执行完毕后才会执行。

十八、var  let  const的区别 

var声明的变量存在变量提升,即变量可以在声明之前调用,var允许重复声明变量var不存在块级作用域

let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错

let和const存在块级作用域

let和const在同一作用域不允许重复声明变量

十九、从浏览器输入url后都经历了什么 

先进行DNS域名解析,先查看本地hosts文件,查看有没有当前域名对应的ip地址,若有直接发起请求,没有的话会在本地域名服务器去查找,没找到的话就去根服务器查找最后查找到对应的ip地址后把对应规则保存到本地的hosts文件中。

进行http请求,三次握手四次挥手建立断开连接。服务器处理,可能返回304也可能返回200

客户端自上而下执行代码渲染页面

二十、HTTP与HTTPS有什么区别 

HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。 

二十一、如何解决前端跨域问题 

JSONP跨域,CORS,nginx代理跨域,nodejs中间件代理跨域,WebSocket协议跨域

二十二、Webpack是什么 

Webpack是一个模块打包工具,可以使用它管理项目中的模块依赖,并编译输出模块所需的静态文件。它可以很好地管理、打包开发中所用到的HTML,CSS,JavaScript和静态文件(图片,字体)等,让开发更高效。对于不同类型的依赖,Webpack有对应的模块加载器,而且会分析模块间的依赖关系,最后合并生成优化的静态资源

二十三、Webpack的基本功能? 

代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等

文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等

代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载

模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件

自动刷新:监听本地源代码的变化,自动构建,刷新浏览器

代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过

自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

二十四、冒泡算法排序 

// 冒泡排序

1.比较相邻的两个元素,如果前一个比后一个大,则交换位置。

2.第一轮的时候最后一个元素应该是最大的一个。

3.按照步骤一的方法进行相邻两个元素的比较,这个时候由于最后一个元素已经是最大的了,所以最后一个元素不用比较。

    function bubbleSort(arr) {

      for (var i = 0; i < arr.length; i++) {

        for (var j = 0; j < arr.length; j++) {

          if (arr[j] > arr[j + 1]) {

            var temp = arr[j]

            arr[j] = arr[j + 1]

            arr[j + 1] = temp

          }

        }

      }

    }

    var Arr = [3, 5, 74, 64, 64, 3, 1, 8, 3, 49, 16, 161, 9, 4]

    console.log(Arr, "before");

    bubbleSort(Arr)

    console.log(Arr, "after")

二十五、快速排序 

    快速排序是对冒泡排序的一种改进,第一趟排序时将数据分成两部分,一部分比另一部分的所有数据都要小。

    然后递归调用,在两边都实行快速排序。  

    function quickSort(arr) {

      if (arr.length <= 1) {

        return arr

      }

      var middle = Math.floor(arr.length / 2)

      var middleData = arr.splice(middle, 1)[0]

      var left = []

      var right = []

      

      for (var i = 0; i < arr.length; i++) {

        if (arr[i] < middleData) {

          left.push(arr[i])

        } else {

          right.push(arr[i])

        }

      }

      return quickSort(left).concat([middleData], quickSort(right))

    }

    var Arr = [3, 5, 74, 64, 64, 3, 1, 8, 3, 49, 16, 161, 9, 4]

    console.log(Arr, "before");

    var newArr = quickSort(Arr)

    console.log(newArr, "after");


网站公告

今日签到

点亮在社区的每一天
去签到