前端面试题汇总

文章目录

1. 函数柯里化

  • 使用:固定部分参数,返回接收剩余参数的函数,
  • 目的:建一个针对性更强的函数
  • 核心思想:把多参数传入的函数,拆成一个个的单参数的函数,内部再返回调用下一个单(或部分)参数的函数,依次处理剩余参数
// 柯里化前
const log = (date, project, message) => {
  return `${date} ${project} ${message}`
}
//输出2022-07-29 xxx后台管理系统 mm接口异常
console.log(log('2022-07-29', 'xxx后台管理系统', 'mm接口异常')) 

//柯里化后
const log = (date) => {
  return (projectName) => {
    return (message) => {
      return `${date} ${projectName} ${message}`
    }
  }
}
//那个参数固定,则传入同一个参数,只改要变的参数
console.log(log('2022-07-29')('A项目')('接口报错')); 

2. get和post的差别

  • 参数:get通过拼接url进行参数传递,参数可见;post通过请求头传递参数,参数不可见
  • 数据携带量:get请求携带的数据不超过2~4k,(浏览器不同,携带量不同,但相差不大);post请求携带量根据配置文件设定,无上限
  • 后退页面的反应: 页面后退,get请求无影响,post请求需要重新提交请求
  • 缓存性:get请求可以缓存,post请求不可缓存
  • 传输速度:get比post更快。(get产生一个TCP数据包;post产生两个TCP数据包)
  • 安全性:原则上post更安全,因为post的数据在url上不可见

@不熟 3. request payload 和 form data之间的区别

  • FormData和Payload是浏览器传输给接口的两种格式,这两种方式浏览器是通过Content-Type来进行区分的。
  • Content-Type是指 HTTP 请求发送信息至服务器时的内容编码类型
  • RequestPayload是(HTTP请求体模式),FormData是(表单请求体模式)

4. HTTP、HTTPs协议详细介绍

1. HTTP协议详细信息

  • HTTP(超文本传输协议),是一种详细规定了浏览器和万维网服务器之间相互通信的规则,通过因特网传送万维网文档的数据传输协议
  • HTTP是基于TCP/IP的应用层协议
  • HTTP不仅能应用于网页浏览,只要通信双方都遵守HTTP协议,都能使用HTTP协议

2. HTTP协议的特点

  • 简单快速:只需传送请求方法和路径
  • 灵活:允许传输任意类型数据对象
  • 无状态:指协议对于事件处理没有记忆能力,缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
  • 支持B/S、C/S模式

3. HTTP工作流程

  • 浏览器与服务器建立连接
  • 浏览器向服务器发送请求
  • 服务器接收请求,
  • 向浏览器返回响应
  • 浏览器接收到响应,渲染页面
  • 断开与服务器的连接

4. HTTP协议请求方式(共8种)

HTTP 1.0 定义了三种(get、post、head)

get:获取,一般用于查询数据,在处理敏感数据时不用,或者参数做加密处理。请求参数拼接在url里

post:一般用于修改数据,数据发送到服务器以创建或更新资源,侧重于更新数据。请求参数在请求body中

head:head方法与get方法相同,但没有响应体,仅传输状态行和标题部分。这对于恢复相应头部编写的元数据非常有用,而无需传输整个内容。

HTTP 1.1 新增了6种(put、delete、pacth、options、trace、connect)

put:一般用于新增数据,数据发送到服务器以创建或更新资源,侧重于创建数据

delete:一般用于删除数据,用来删除指定的资源,它会删除URI给出的目标资源的所有当前内容

pacth:用于资源的部分内容的更新;会在资源不存在时去创建它(有则修改,无则添加)

options:用来描述了目标资源的通信选项,返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送`*`的请求来测试服务器的功能性

trace:用于沿着目标资源的路径执行消息环回测试;它回应收到的请求,以便客户可以看到中间服务器进行了哪些(假设任何)进度或增量。

connect:用来建立到给定URI标识的服务器的隧道;它通过简单的TCP / IP隧道更改请求连接,通常是使用解码的HTTP代理来进行SSL编码的通信(HTTPS)

5.HTTP协议状态码

100~199: 提供信息。

200~299: 请求被成功提交。

300~399: 客户端被重定向到其他资源。

400~499: 请求包含某种错误。

500~599: 服务器执行请求时遇到错误。

6.HTTPS

  • 与http的区别:安全性比http高,是HTTP 的安全版
  • 主要作用:建立一个信息安全通道,来确保数据的传输,确保网站的真实性
  • 优点:确保数据发送到正确的客户端和服务器,确保数据的完整性,大幅度增加了中间人攻击的成本
  • 缺点:增大了与服务器握手时间(大约增加了50%),SSL证书需要收费

5.v8引擎的AST是什么

  • V8引擎是使用AST(抽象语法树)来解析和转换js代码的
  • AST是解析和转换JavaScript代码的树状结构表示,它提供了一种便捷的方式来分析、修改和转换代码。

6.BFC

  • BFC是块级格式化上下文,可以把BFC看成一个容器,容器内的元素不会影响到外部元素
  • BFC的特性
1. BFC是块级元素,在垂直方向上依次排列
2. BFC是独立容器,内部元素不会影响到外部元素
3. 同一个BFC里面的两个盒子,外边距会发生重叠,并取最大外边距
4. 计算BFC高度时,浮动元素也要参与计算
  • 创建BFC
1. overflow:hidden      隐藏的内容
2. display:flex         转变为弹性盒子,变现为块级元素
3. position:abssolute   绝对定位
4. position:fixed       固定定位
5. display:inline-flex  转变为弹性盒子,变现为行内块元素
6. display:inline-block 转变为行内块元素
  • BFC的作用:
1. 解决父元素未设置高度,子元素浮动造成父元素高度塌陷的问题
2. 解决子元素外边距错误的加到父元素上的问题

7.文档流

CSS 有三种基本的定位机制:普通流、浮动流、定位流。

文档流(标准流、普通流)

  • html的默认排版方式
  • 特点:块级元素上下排列,行内块元素、行内元素左右排列

浮动流

  • 脱离标准流的排版方式,使用float:none/left/right实现
  • 特点:
1. 浮动后的元素只有居左、居右、无三种属性,
2. 浮动后的元素可以设置宽高
3. 元素只在父元素宽高范围内浮动
4. 浮动后的元素不可使用margin:0 auto;
5. 元素浮动后,后面的同级元素会占据他原本的位置
6. 如果两个浮动的元素的宽之和小于父元素宽,左右排列
7. 如果两个浮动的元素的宽之和大于父元素宽,上下排列

定位流

  • 定位分为相对定位、绝对定位、固定定位、静态定位(文档流默认定位)
  • 相对定位不脱离文档流,绝对定位、固定定位会脱离文档流
  • z-index属性是专门控制定位流元素的覆盖关系

8.布局方案

  1. 居中布局(水平居中、垂直居中、水平垂直居中)
  2. 双飞翼布局(侧边两栏宽度固定,中间栏宽度自适应)
  3. 圣杯布局(侧边两栏宽度固定,中间栏宽度自适应)
  4. 栅格布局

9.浏览器从发出请求到接受响应,中间过程

1. 用户输入url,生成http请求

2. 解析域名,得到IP地址。(根据url域名从本地hosts文件查找是否有映射IP,如果查找不到,则将域名发送给电脑所配置的DNS进行域名解析,得到IP地址)

3. 建立TCP连接(三次握手)

4. 向服务器发送HTTP请求

5. 服务器收到请求

6. servlet处理请求

7. 将响应结果封装成 HTTP 响应的格式,发送给浏览器,关闭TCP连接,请求响应完成

8. 浏览器收到响应数据,解析并渲染响应页面

10.前端存储

优势

  1. 方便网页加载,避免了在发送请求收到响应前的空白期
  2. 减少向服务器的请求次数,加快渲染速度
  3. 在网络不佳或无网络时,也可以离线浏览网页

存储方式

分为存储类(cookie、localStroage、sessionStroage)、缓存类(Cache Storage、Application Cache)

存储类
1、2. Web Storage(localStorage、sessionStorage)
  HTML5提出的存储方式,容量5M

  优点:
    1. 克服了cookie的限制,同时存储一些要严格控制在客户端,不需要发送给服务器的数据
    2. 提供了除cookie之外的存储会话途径
    3. 存储容量大,跨会话存储数据
  localStorage:
    1. 永久存储,除非自动删除
    2. 保存在客户端,不与服务器进行交互通信
    3. 只能存储字符串类型,复杂数据类型会转化为json字符串保存
    4. 应用场景:适合长期保存在本地的数据
    5. 操作localStorage
      //设置localStorage,有则修改,无则添加
      //将键值对存储在localStorage中
      localStorage.setItem("key", "value");

      // 获取localStorage
      var value = localStorage.getItem("key");

      //删除localStorage
      localStorage.removeItem("key");

      //清空localStorage
      localStorage.clear();
  sessionStorage:
    1. 当前会话下有效,关闭浏览器,数据清除
    2. 保存在客户端,不与服务器进行交互通信
    3. 只能存储字符串类型,复杂数据类型会转化为json字符串保存
    4. 应用场景:敏感账号、一次性登录
    5. 操作sessionStorage
      //设置localStorage,有则修改,无则添加
      //将键值对存储在localStorage中
      sessionStorage.setItem("key", "value");

      // 获取localStorage
      var value = sessionStorage.getItem("key");

      //删除localStorage
      sessionStorage.removeItem("key");

      //清空localStorage
      sessionStorage.clear();
3.cookie
  基于HTTP协议的存储方式,浏览器普遍支持,容量4k
  限制性:需要设置过期时间,过期自动清除,如果不设置,浏览器关闭就清除
  优点:
    1. 可以控制过期时间,有一定的安全保障
    2. 可进行扩展,可跨域共享
    3. 通过加密与安全传输技术(SSL),可降低cookie被破解的风险
    4. 有较高的兼容性
  缺点:
    1. 有数量和长度限制,每个cookie长度不能超过4kb,超过部分会被截掉
    2. 请求头上的数据容易被拦截攻击
  //操作cookie
    //获取cookie:
      //获取所有cookie
        var cookies = document.cookie;
        //返回的是一个字符串,形如"cookie1=value1; cookie2=value2"
        //使用splice(;)方法将字符串截并存储在数组中,方便提取数据

  //修改cookie:有则修改,无则添加
    document.cookie = "name=value; expires=expiration_date; path=path; domain=domain; secure";
    //name是Cookie的名称,value是Cookie的值。
    //expires是失效日期,格式为"Mon, 28 Jun 2023 13:24:25 GMT"。
    //path是可访问该Cookie的路径,默认是当前文件路径。
    //domain是可访问Cookie的域名,默认是当前域名。
    //secure指定Cookie只在使用HTTPS连接的情况下才发送。

  // 删除cookie:
    document.cookie="要删除的键名=随便; expires=一个过去时间的GMT格式"
  sessionStorage、localStorage与cookie的区别

  1. 存储空间更大

  2. 节省网络流量

  3. 安全性更高,不用担心被截取

  4. 三者都是只能储存字符串,如果用WebStorage(sessionStorage、localStorage)存储对象,会出现 [Object Object], 可以用 JSON.stringify 与 JSON.parse方法来解决这个问题。

  5. sessionStorage、localStorage以(key,value)的形式存储数据,cookie以键1=1的形式存储数据

  6. sessionStorage、localStorage是作为window对象的属性存在,可以直接通过window.sessionstorage、window.sessionstorage来访问
4. IndexDB
5. Web SQL
缓存类
1. Cache Storage
2. Application Cache

11.vite和webpack的区别

  • Vite和Webpack都是现代化的前端构建工具,用于打包、编译、压缩和优化前端代码。
  • 主要目的是将多个源文件(例如JavaScript,CSS和HTML文件)打包成更少的文件,以便在浏览器中加载更快,同时提供许多其他功能。
  • 相同点
  1. 都可以处理各种静态资源,例如HTMLCSS、JavaScript、图片和字体等

  2. 都支持模块化开发,可以使用ES Modules、CommonJS、AMD等模块规范

  3. 都支持开发模式和生产模式,可以对代码进行压缩、混淆和优化等处理

  4. 都支持插件机制,可以扩展和定制构建流程

  5. 都可以处理热模块替换(HMR),在开发过程中快速更新修改的代码
  • 不同点
  1. 构建方式不同
    Webpack采用静态依赖关系,需要在配置文件中声明入口文件和输出文件,并通过loader和plugin进行配置。Webpack的构建方式比较复杂

    Vite采用动态导入方式,通过本地服务器实现快速构建和启动。Vite的构建方式比较简单,无需配置多个入口文件和输出文件,同时可以自动识别模块依赖关系

  2. 速度不同
    Webpack在处理大型项目时,构建速度可能会变慢。这是因为Webpack在进行打包时,需要处理所有的模块,包括未使用的模块。这使得Webpack的构建速度变慢

    Vite采用了按需编译方式,只会编译当前页面的相关模块,而不会处理未使用的模块。这使得Vite的构建速度更快,可以快速启动项目和进行热更新

  3. 适用范围不同
    Webpack适用于大型复杂的Web应用程序,可以处理各种类型的静态资源,并提供了强大的插件机制,可以满足各种复杂的构建需求

    Vite适用于中小型Web应用程序,以及需要快速启动和热更新的开发场景。Vite提供了快速构建和启动的能力,可以让开发者更加专注于业务逻辑的开发
  • 总结
  1.如果需要构建大型项目或对模块化支持有较高要求,那么Webpack是比较好的选择
  
  2.而如果是在开发模式下需要快速迭代,并且对性能有要求,那么Vite则是一个很好的选择

12.状态管理存储 , localstorage

@不熟 13.H5新特新:Web Worker、WebSocket

  • Web Worker
  • WebSocket

14.Vue 生命周期的理解

vue2

1. beforeCreate()
实例完全被创建之前,会执行这个函数
beforeCreate()执行时,data和methods中的数据还没有被初始化

2. created() 
在created中,data和methods都已经被初始化好了
如果要调用methods中的方法,或者操作data中的数据,最早只能在created中操作

3. beforeMount()
模板已经在内存中编译完成,但是尚未把模板渲染到页面中

4. mounted()
内存中的模板已经真实的挂载到页面中,用户已经可以看到渲染好的页面

5. beforeUpdate()
当执行beforeUpdate的时候,页面中的显示的数据还是旧的,但data数据是最新的,页面尚未和最新的数据保持同步

6. updated()
updated事件执行的时候,页面和data数据已经保持同步了,都是最新的

7. beforeDestroy() 
实例销毁前调用vm.$destroy()时触发,实例被销毁的前夕

8. destroyed()
实例销毁完毕,该钩子被调用后,对应Vue实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。(以后页面就无法动态更新数据了。也就是说无法数据驱动视图。)

  • vue2常用的生命钩子
1. mounted(执行一些初始化操作):发送ajax请求、启动定时器、绑定自定义事件、订阅消息
2. beforeDestroy(执行一些收尾工作):清除定时器、解绑自定义事件、取消订阅消息
  • 关于销毁vue实例
1. 销毁后借助Vue开发者工具看不到任何信息。
2. 销毁后自定义事件会失效,但原生DOM事件依然有效。
3. 一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。

vue3选项式

  • vue3选项API,生命周期钩子是被暴露Vue实例上的选项,只需要调用这个方法并为这个生命周期钩子编写代码。
  • vue3选项式API生命周期与vue2大致相同,beforeDestroy()、destroyed()改为beforeUnmount()、unmounted(),实际上作用和用法是一样的

vue3组合式

1. steup 创建实例前
2. onBeforeMount 挂载DOM3. onMounted 挂载DOM4. onBeforeUpdate 更新组件前
5. onUpdate 更新组件后
6. onBeforeUnmount 卸载销毁前
7. onUnmounted 卸载销毁后 
  • 总结
1. 与vue2、vue选项式想比,去掉了两个生命周期API(beforeCreate、created),添加了setup
2. 方法名发生变化,名称前多了on,中间使用驼峰式命名
3. 卸载组件的生命周期变化:onBeforeUnmount 、onUnmounted
4. 同一个生命周期可以触发多次

15.谈一谈对 MVVM 的理解?

  • MVVM是 Model-View-ViewModel 的缩写

Model:数据模型
View:ui组件
ViewModel:一个同步View 和 Model的对象,连接Model和View

  • 在MVVM架构下,viewmodel通过双向数据绑定把model与view连接起来,model与view没有直接联系,
  • model与view之间的交是相互的,因此view数据的变化会同步到model中,model数据的变化也会立即反应到view上
  • model和view之间的同步工作是完全自动的,无需人为操作

16.Vue 实现双向数据绑定的原理?

vue2

  • 在组件创建时,vue会对对组件的data中的每个属性进行代理
  • 当组件中任何一个属性发生变化时,vue会通过Object.defineProperty()方法重新定义该属性的setter方法,从而在属性被重新赋值时触发对应的wather更新对应的DOM节点

vue3

  • Vue3的双向数据绑定底层使用了Proxy API来进行代理。
  • 在组件创建时,Vue3会对组件的data中的每个属性进行代理,使用了Proxy中的handler中的set方法,当组件中的任何一个属性发生变化时,就会触发set方法,从而更新对应的DOM节点。

17.Vue2.x 中如何检测数组的变化?

  • 通过vue重写后的7个数组方法(push,pop,shift,unshift,sort,splice,reverse)检测数组的变化
  • vue将data中的数组,进行了原型链重写。通过原型链指向了重新定义后的数组方法,当调用数组api时,可以通知依赖更新。如果数组中包含引用类型,会对数组内的引用类型再次监控

不熟@ 18.vue2.x 和 vuex3.x 渲染器的 diff 算法分别说一下?

vue2

vue3

19.Vue 的路由实现

  • 路由的原理: 通过改变URL,在不重新请求页面的情况下,更新页面视图
  • 有两种:HashHistory路由、history路由

HashHistory路由

  • vue默认使用hash路由
  • hash(‘#’)的作用是加载url中指示的网页的位置
  • HashHistory路由的特点
1. 路由地址会有#
2. `#`后面的内容不会传给服务器,也就是说不会重新刷新页面,路由切换也不会重新加载页面
3. 每次改变hash(window.localtion.hash),都会在浏览器增加一个历史记录
  举例:
  http://localhost:8080/#/a 
  //变为 如下地址,浏览器访问历史中会增加一个记录
  http://localhost:8080/#/b 
4. 可以为hash的改变添加监听事件`window.addEventListener("hashchange",funcRef,false)`  
  • HashHistory路由的两个方法
1. hashHistory.push() 将路由添加到浏览器访问历史的栈顶,之前的路由还存在,可以返回之前路由

2. hashHistory.replice()  将路由替换掉当前路由,当前路由会成为最新路由,之前的路由会被覆盖,无法返回之前路由

history路由

  • HIstory interface是浏览器历史记录栈提供的接口,通过back()、forward()、go()等方法,可以读取浏览器历史记录栈的信息,进行各种跳转操作
  • history路由原理
利用History interface在H5中新增方法pushState()、replaceState(),对浏览器历史记录栈进行修改
  • 特点
1. history路由模式,实现单页面的url中没有#,当用户改变路由时,会向服务器发送请求
2. 为了避免这种情况,所以history路由实现方式需要服务器的支持,需要把所有的路由都定向到根页面
3.HTML5 History 的构造函数中监听使用popState(window.onpopstate)
  • history路由的两个方法
// stateObject:当浏览器跳转到新的状态时,将触发Popstate事件,该事件将携带这个stateObject参数的副本
// title:所添加记录的标题
// url:所添加记录的url

// 和hashHistory.push()功能相似,将路由添加到浏览器访问历史的栈顶,之前的路由还存在,可以返回之前路由
window.history.pushState(stateObject,title,url) 

//和hashHistory.replace()功能相似,将路由替换掉当前路由,当前路由会成为最新路由,之前的路由会被覆盖,无法返回之前路由
window.history,replaceState(stateObject,title,url)  

两种路由模式的区别

  1. history模式设置的新的URL可以是与当前URL同源的任意URL
    hash模式只可修改#后边的部分,故只可设置与当前文档同文档的URL
  2. history模式通过stateObject可以添加任意类型的数据到记录中
    hash模式只可添加短字符串
  3. history模式可额外设置title属性后供后续使用
    hash模式没有该功能
  4. history模式会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应的路由处理,则会返回404错误
    hash模式只改变#后面的内容,跳转路由不刷新页面,故不会向后端发送请求

两种路由模式跳转API的区别

APIhash模式history模式
pushhashHistory.push()window.history.pushState()
replicehashHistory.replice()window.history,replaceState()
gowindow.history.gowindow.history.go
backwindow.history.go(-1)window.history.go(-1)
forwardwindow.history.go(1)window.history.go(1)

20.vuex和pina的区别?

vuex

  • 核心属性:
1. state:单一状态树,用来存储所有的共享数据
   //调用方法:
   this.$store.state.全局数据名称

2. getters:状态获取,相当于`state`的计算属性,具有返回值的方法
   //调用方法:
   this.$store.getters.方法名

3. mutation:触发同步事件,用于修改state中存储的数据
   //建议通过mutation操作state中的数据,虽然操作复杂,但可以集中监控state里所有数据的变化
   //直接操作state,state里的数据是无法监控的
   //Mutation中不可以执行异步操作,如需异步,在Action中处理
   //调用方法:
   this.$store.commit('方法名',)

4. actions:触发异步事件,用于处理异步任务的,比如网络请求等
   //调用方法:
   this.$store.dispatch('方法名',)

5. module:将vuex进行模块拆分
   //模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理
  • 总结
  1. 修改state状态必须通过mutations
  2. mutations只能执行同步代码,类似ajax、定时器之类的代码不能在mutations中执行
  3. 执行异步代码,要通过actions,然后将数据提交给mutations才可以完成
  4. state的状态即共享数据可以在组件中引用
  5. 组件中可以调用action

pinia

  • 核心属性
1. state:用来储存全局的数据
   //访问state:
   const store=useStore()
   store.变量名
   //重置state:
   const store=useStore()
   store.$reset()

2. getter:监视计算状态的变化,有缓存功能
   //Getter 等同于 store 的 state 的计算值
   //调用方法
   const store = useStore()
   store.方法名

3. action:修改state内的全局状态数据
   //调用方法
   const store = useStore()
   store.方法名

vuex与pinia的区别

  • Vuex和Pinia都是Vue.js的状态管理库
  • 区别
  1. vuex是vue.js官方提供的状态管理库<br>
    pinia是基于vue3且使用TS编写的轻量级状态管理库
  2. vuex提供了更完整、更复杂的接口和功能集,如模块、插件等<br>
    pinia只提供了片段式组装store等核心需求
  3. vuex相对稳定,文档和社区支持完善<br>
    pinia侧重于TS风格的开发方式,未来可能会提供更好的维护性和易读性

21.nextTick 的作用是什么?他的实现原理是什么?

  • vue中DOM更新是异步的
  • vue实现响应式不是数据发生变化后,DOM立即变化,而是按一定的策略进行DOM更新的
  • 作用

用于下次DOM更新循环结束后执行回调,在修改数据之后使用 nextTick,则可以在回调中获取更新后的DOM

  • 应用场景
  1. 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中<br>
    原因:在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的 js 代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题
  2. 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。<br>
  3. 需要在视图更新后,基于新的视图进行操作
  • 实现原理

nextTick主要是使用了宏任务、微任务,定义了一个异步方法,多次调用 nextTick会将方法存入队列中,通过这个异步方法情况队列

22.热更新

  • 当代码发生变化时,页面会根据更新后的代码发生变化,无需重新加载页面

23.服务端渲染(SSR)

1. SSR(server side render)服务端渲染
2. CSR(client side render)客户端渲染
3. SPA(single page application)单页面应用
4. SEO(search engine optimization)搜索引擎优化
5. SSGstatic side generate)预渲染
6. AJAX(Asynchronous Javascript And XML)在不重新加载整个网页的情况下,对网页的局部数据进行更新

什么是服务端渲染

服务器端完成页面的DOM结果拼接,然后发送到浏览器,为其绑定状态和事件,成为完全可交互的过程

优点

  1. 前端耗时少,因为后端拼接完html,前端只需直接渲染出来
  2. 有利于SEO,因为在后端有完整的html页面,有利于爬虫爬取信息,更利于SEO
  3. 降低占用客户端资源,因为解析模板的工作完全交给后端,客户端只需解析标准的html页面即可,对客户端的资源占用更少,尤其是移动端,更省电
  4. 后端生成静态化文件,可以降低数据查询浪费的时间,对于数据变化不大的页面非常高效

缺点

  1. 不利于前后端分离,开发效率低
  2. 占用服务器端资源

服务器端渲染的方式

  1. JSP(JavaServer Pages)
  2. express + ejs
  3. express + react
  4. vue + nuxt

应用场景

  • 适用于客户端渲染的项目
  1. 企业内部项目,管理平台这类不需要SEO的项目,使用客户端渲染能能够提高开发效率,减少服务器资源占用;
  2. 强交互项目:对于交互比较多,数据不是很固定的项目,使用客户端渲染,能够让用户更临近于原生APP体验;
  • 适用于服务端渲染的项目
  1. 官网、博客网站、营销类网站:这些网站对SEO和首屏渲染速度更加注重,所以服务端渲染会是较好的选择;

24.react-hooks

  • 什么是hooks

hooks意思是钩子,react hooks就是一堆钩子函数

  • 作用

对函数型进行增强,让函数组件可以存储状态,可以用有处理副作用的能力,让开发可以在不使用类组件的i情况下,实现相同功能

  • 副作用
  1. 代码中只要不是把数据转换成视图的代码他就属于副作用
  2. 副作用代码:发送ajax请求,获取dom,添加点击事件
  3. 在类型组件中,一般使用生命周期函数去处理副作用,而在这些函数型组件中,我们就要使用hooks去处理这些函数
  • 常见的react hooks

1. useState()

  • 作用:用于函数组件引入状态
  • useState()方法内部是使用闭包保存状态数据的
  • 使用细节
1. 接收唯一的参数即状态初始值。初始值可以是任意数据类型
2. 返回值为数组。数组中存储状态值和更改状态值的方法。方法名称约定以set开头。后面加上状态名称 
3. 方法可以被多次调用,用以保存不同的状态值
4. 参数可以是一个函数,函数返回什么,初始值就是什么,函数只会被调用一次,用在初始值是动态值的情况

2. useReducer()

  • 作用:让函数组件保存状态
  • 使用方式和rudux的reducer相似,状态都被保存在一个特殊的地方
  • 使用细节
第一个参数就是reducer函数,我们创建reducer函数去进行对数据的处理,
第二个参数为状态的初始值

函数的返回值返回一个数组,数组里面有两个值一个是存储的状态,第二个是触发action的dispatch方法

自己创建的reducer函数接受两个值,一个是存储的状态另外一个就是触发的action

3. useContext()

  • 作用:在跨组件层级获取数据时简化代码

4. useEffect()

  • 作用:让函数型组件拥有处理副作用的能力。类似生命周期函数

5. useMemo()

  • 作用:类似Vue中的计算属性,可以检测某个值得变化,根据变化值计算新值
  • useMemo会缓存计算结果。如果检测值没有发生变化,即使组件重新渲染,也不会重新计算
  • 有助于避免在每个渲染上进行昂贵的计算

6. useCallBack()

  • 作用:性能优化,缓存函数,使组件重新渲染时得到相同的函数实例
  • 使用场景:
当子组件通知父组件的时候,子组件内部状态没有发生改变但是还是进行了重新渲染,memo虽然解决
子组件内部状态没有变阻止子组件重新渲染问题,但是当父组件状态改变,组件发生了重新渲染,
新渲染过后每一次生成的改变状态的函数的实例都变了,导致传递给子组件的方法中的实例变了,
传入的函数实例改变,子组件就会认为组件内部的状态发生了改变,他就会导致重新渲染。解决这
问题的方法就是让传给子组件的函数实例都是同一个这里就要用到useCallBack()

7. useRef()

  • 作用:获取dom元素对象,保存数据(跨组件周期)

8. 自定义hooks

  • 自定义hook是标准的封装和共享逻辑的方式
  • 自定义hook是一个函数,其名称以use开头
  • 自定义hook其实就是逻辑和内置Hook的组合

9. React路由Hooks

  • 包含了四个钩子函数

useHistory()
useLocation()
useRouteMatch()
useParams()

  • 作用:获取相关的路由信息

25.redux

  1. 相当于vue中的vuex
  2. redux 是一个独立专门用于做状态管理的 JS 库(不是 react 插件库)
  3. 它可以用在 react, angular, vue 等项目中, 但基本与 react 配合使用
  4. 作用: 集中式管理 react 应用中多个组件共享的状态
  5. 核心概念
  • Store
1. 在 redux 里面,只有一个Store,整个应用需要管理的数据都在这个Store里面。
2. 不能直接改变Store的数据,只能通过返回一个新的Store去更改它。
3. redux提供了一个createStore()方法来创建state
  • action
视图层发起的一个操作,通过action改变store内的数据
  • Reducer
作用:调用action里的方法
在redux里面,store.dispatch()是 View发出 Action 的唯一方法

26.call、apply、bind的作用和区别

共同点

  • 都可以改变函数内部的this指向

不同点

  1. call和apply会调用函数,并且改变函数内部this指向。
  2. call和apply传递的参数不一样,call传递参数arg1,arg2…形式apply必须数组形式[arg]
  3. bind不回调用函数,可以改变函数内部this指向。

call()方法

  1. 改变函数内部this指向,同时调用该函数
  2. 语法:
fun.call(thisArg,arg1,arg2,...)
//thisArg为想要指向的对象,arg1,arg2为参数
  1. 应用场景:实现继承

apply()方法

  1. 改变函数内部this指向,同时调用该函数
  2. 语法
un.apply(thisArg,[argsArray])
//thisArg:在fun函数允许时指定的this值
//argsArray:传递的值,参数必须放在数组里面
//返回值就是函数的返回值
  1. 应用场景:求数组中最大值

bind()方法

  1. 改变函数内部this指向,不会调用该函数
  2. 语法
fun.bind(thisArg,arg1,arg2,...)
//thisArg:在fun函数运行时指定的this值
//arg1,arg2:传递的其他参数
//返回由指定的this值和初始化参数改造的原函数拷贝
  1. 应用场景:有的函数我们不需要立即调用,但是又需要改变这个函数的this指向,此时用bind再合适不过了

27.this指向

概念

在js中,this是一个指针型变量,它动态指向当前函数的运行环境
在不同的场景中调用同一个函数,this的指向也可能会发生变化,
永远指向其所在函数的真实调用者;如果没有调用者,就指向全局对象window

this的指向

  1. 普通函数:
  • 严格模式下,必须要写调用该函数的对象,有则this指向该对象,无则undefined
  • 非严格模式下,this指向调用该函数的对象
  //在严格模式下,对代码的的调用必须严格的写出被调用的函数的对象,不可以有省略或者说简写。
  function fn(){
    "use strict"  //使用严格模式
    console.log(this);
  }
  fn()//输出undefined
  window.fn()//输出window

//非严格模式下,通过test()和window.test()调用函数对象,this都指向window。
  function fn(){
    console.log(this);
  }
  fn()//输出window
  window.fn()//输出window
  1. 箭头函数:箭头函数的this指向于函数作用域所用的对象
1. 创建箭头函数时,就已经确定了它的 this 指向。
2. 箭头函数内的 this 指向外层的 this。所以要知道箭头函数的 this 就得先知道外层 this 的指向
  1. 在全局作用域下,this始终指向全局对象window,无论是否是严格模式
  //全局作用域下的this指向
  //console.log()完整的写法是window.console.log(),window可以省略
  //window调用了console.log()方法,所以此时this指向window

  console.log(this) //输出window
  1. 对象中的函数:
  • 普通函数:this指向对象
  • 箭头函数:this指向window
let obj={
  a:()=>console.log(this),
  fn(){console.log(this)}
}
obj.a()  //输出window
obj.fn() //输出{a: ƒ, fn: ƒ}
  1. 构造函数
1. 当使用 new 关键字调用构造函数时,函数中的 this 指向实例新对象
2. 直接调用,this指向调用者

  1. 事件绑定中的this
1. 行内绑定,this指向window
2. 动态绑定与事件监听,this指向节点对象
  1. 改变this指向的方法:call()、apply()、bind()
//call()方法,改变this同时调用函数
函数名称.call(obj,arg1,arg2…argN);

//apply()方法,参数二是一个数组,改变this同时调用函数
函数名称.apply(obj,[arg1,arg2…,argN]);

//bind()方法,和call类似,改变this,但不会调用函数
函数名称..bind(obj);

28.垃圾回收机制

  • 什么是垃圾
  1. 没有引用的对象或变量
  2. 无法访问到的对象(多个对象相互引用成环)
  • 垃圾回收机制

间歇的不定期的寻找那些不再使用的对象或变量,并释放掉他们占用的内存
目的:防止内存泄漏,减小浏览器内存压力

  • 检测垃圾的方式:标记清除法、引用计数法

标记清除法

当函数执行开始,给函数内的变量打上“进入环境”的标记,当函数执行结束后,不再被引用的变量标记为“离开环境”,将这些标记为“离开环境”的变量删除

29.EventLoop(事件循环)

  1. 同步任务 > nextTick > 其他微任务 > 宏任务
  2. 宏任务:I/O、定时器、事件绑定、ajax
  3. 微任务:Promise的then、catch、finally和process的nextTick
  4. Promise的then等方法是微任务,而Promise中的代码是同步任务

30.内存溢出和内存泄漏

内存泄露

  • 用动态储存分配函数内存空间,在使用完毕后未释放,导致一直占据该内存单元,直到程序结束。
  • 常见的内存泄漏:闭包、计时器、回调、事件监听
  • 无用的变量占据了有用的内存

内存溢出

  • 不顾堆栈分配的局部数据块大小,向数据块中写入过多数据,导致数据越界,结果覆盖了别的数据。常在递归中发生。
  • 内存溢出一般是内存泄漏造成的,会造成浏览器内存不足,崩溃掉
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
2023年前端面试题汇总包括以下问题: 1. 请解释下什么是响应式设计(Responsive Design)? 响应式设计是一种设计和开发网站的方法,使其能够在不同设备上提供最佳的用户体验。通过使用媒体查询、弹性网格布局以及其他技术手段,网站可以根据设备的屏幕大小和特性自适应地调整布局和样式。 2. 谈谈你理解的盒模型(Box Model)? 盒模型是指在网页布局中,每个元素都被看作是一个矩形的盒子。它由内容区域(content)、内边距(padding)、边框(border)和外边距(margin)组成。这些部分共同决定了元素在页面中的尺寸、位置以及与其他元素之间的间距。 3. 解释一下什么是跨域(Cross-Origin Resource Sharing,CORS)? 跨域指的是在浏览器发送请求时,当前页面所在的域与该请求要访问的资源所在的域不一致。出于安全原因,浏览器会限制跨域请求。CORS 是一种机制,允许服务器在响应中设置一些头部信息,告诉浏览器该服务器允许哪些跨域请求。 4. 如何优化网页的加载性能? 有多种方法可以优化网页的加载性能,以下是一些常见的技术: - 使用浏览器缓存,减少对服务器的请求次数。 - 压缩和合并 CSS 和 JavaScript 文件,减小文件大小。 - 使用懒加载和延迟加载来延迟加载非关键资源。 - 优化图片,使用适当的格式和压缩算法。 - 使用 CDN(内容分发网络)来加速资源的加载。 - 减少 HTTP 请求次数,合并和内联文件。 - 优化服务器响应时间,减少网络延迟。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值