近期前端面试题总结

615 阅读13分钟

最近有在新找工作,自己准备以及面试官面试的一些前端面试题总结:

高频(以20次面试为底)

1. 深拷贝和浅拷贝区别(几乎每次面试都问 18/20)

浅拷贝——复制只复制某个对象的指针,公用一个内存块 深拷贝——新建一个一模一样的对象,各自独立,与原对象不共享内存,修改新对象不会改变原对象 ①浅拷贝:只复制引用,而未复制真正的值

	var arr1 =「'a','b',"c','d'];
	var arr2 = arr1;
	var obj1={a:1,b:2}
	var obj2=0bject.assign(obj1);

②深拷贝:是复制真正的值(不同引用)

	var obj3 ={a:1,b:2
	var obj4=JSoN.parse(JSoN.stringify(obj3))  // 序列化反序列化

2. vue的生命周期(大部分面试会问 13/20)

beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。

    console.log('beforeCreate: 实例完全被创建出来之前,data 和 methods 等都没有
    console.log('created: 实例创建完成,属性已经绑定,但DOM还未生成,$el属性不存在');
    console.log('beforeMount: 模板编译之前,此时已经完成了v-if的判断');
    console.log('mounted: 模板编译完成,此时DOM已经生成,可以访问到DOM元素
    console.log('beforeUpdate: 数据更新时调用,此时data中的状态值是最新的,但是页面上显示的数据还是旧的');
    console.log('updated: 数据更新完成后调用,此时data中的状态值和页面上显示的数据都是最新的');
    console.log('beforeDestroy: 实例销毁之前调用,此时实例仍然完全可用');
    console.log('destroyed: 实例销毁后调用,此时所有的事件监听器会被移除,所有的子实例也会被销毁');

面试官大部分会接着问你处理数据一般在那个生命周期中; 比如像我回答的话就说一般在mounted里面

3. vue通信方式(几乎每次都问 15/20)

Props / Events:父子组件之间的通信。 Vuex:状态管理,用于管理大型应用中的状态流。 Vue Router:用于vue应用的路由管理。 Provide / Inject:父子组件之间的跨级通信。 $Emit:子传父值 Emit / Listen:用于非父子组件之间的通信,可以通过事件总线。

4.vue导航守卫钩子(8/20)

beforeEach, beforeResolve 和 afterEach beforeEach: 全局前置守卫,主要用于页面跳转前的操作,比如登录验证、权限判断、取消未完成的网络请求等。 beforeResolve: 2.5.0+ 新增,主要用于解析守卫,在afterEach和beforeEach之后调用,用于响应式路由参数的变化。 afterEach: 路由跳转后的操作,比如标题的修改、页面滚动到顶部等。

image.png

5. 本地缓存cookie、localstorage、sessionstorage(18/20)

Cookie是网站为了标示用户身份而储存在用户本地终端上的数据(通常是小的文本文件)。 localStorage是HTML5新增的一个功能,可以用来储存键值对数据。 sessionStorage与localStorage类似,也是存储键值对数据。但它只是针对一个session的,当用户关闭浏览器窗口后,数据会被清除。

Removeitem手动清除

  • 数据存放有效期 sessionStorage:仅在当前浏览器窗口关闭之前有效。【关闭浏览器就没了】 localStorage:始终有效,窗口或者浏览器关闭也一直保存,所以叫持久化存储。 cookie:只在设置的cookie过期时间之前有效,即使窗口或者浏览器关闭也有效。
  • localstorage、sessionstorage不可以设置过期时间 cookie 有过期时间,可以设置过期(把时间调整到之前的时间,就过期了
  • 存储大小的限制 cookie存储量不能超过4k localStorage、sessionstorage不能超过5M

6.项目部署优化,性能优化(8/20)

  • 尽量不要在前端渲染数据的时候计算太复杂 尤其是 表格
  • 懒加载
  • 使用CDN加速资源
  • 删除不用 NPM依赖
  • 分包
  • 项目中的 v-for 代码 都加上 :key,提高循环性能
  • 实在数据量大,使用虚拟滚动 实现
  • 去除不必要的输出

  • 代码压缩与优化:使用工具如TerserPlugin进行代码压缩,移除未使用的代码和注释。删除未使用的npm依赖
  • 懒加载:使用动态导入(异步组件)来实现路由组件的懒加载,减少初始加载大小。
  • 预渲染:对于静态内容可以使用预渲染生成静态HTML文件。 web字体优化:优化字体加载策略,如使用Font Face Observer来确保文字渲染后再显示内容。
  • 图片优化:使用懒加载和优化图片大小,减少请求数量和图片加载时间。使用CDN方式引入
  • 使用SSR(服务器端渲染):对于SEO友好的页面,可以使用Nuxt.js框架进行SSR配置。
  • 性能监控与分析:使用性能监控工具如Lighthouse、PageSpeed Insights定期分析和优化性能。

7.Vuex(12/20)

State:单一状态树,用于存储应用中的数据和状态。(全局共享属性)(辅助函数mapState) Getters:从State生成的数据。可以认为是Store的计算属性。(辅助函数mapGetters) Mutations:同步函数,用于更改State中的数据。 Actions:异步函数,用于提交Mutations。存放异步方法 Modules:模块化Vuex,允许将store分割成模块。

8.数组去重

function removeDuplicates(array) {  
    return [...new Set(array)];  
}    
// 使用示例  
const arr = [1, 2, 2, 3, 4, 4, 5, 5, 5];  
const uniqueArr = removeDuplicates(arr);  
console.log(uniqueArr); // 输出: [1, 2, 3, 4, 5]
function removeDuplicates(array) {  
    return array.filter((item, index) => {  
        return array.indexOf(item) === index;  
    });  
}   
const arr = [1, 2, 2, 3, 4, 4, 5, 5, 5];  
const uniqueArr = removeDuplicates(arr);  
console.log(uniqueArr); // 输出: [1, 2, 3, 4, 5]

9. routeroute和router的区别

this.router:是router实例。通过this.router:是 router 实例。通过 this.router 访问路由器,相当于获取了整个路由文件,在router.option.routes中,或查看到当前项目的整个路由结构具有实例方法this.router.option.routes中,或查看到当前项目的整个路由结构 具有实例方法 this.route:当前激活的路由信息对象。这个属性是只读的,里面的属性是 immutable (不可变) 的,不过可以 watch (监测变化) 它。通过 this.$route 访问的是当前路由,获取和当前路由有关的信息

image.png

10. 数据更新视图没有更新的问题(5/20)

this.$set(target,key,修改后的值)

this.$forceUpdate()

11.闭包(15/20)

就当做在一个环境里头新开辟了一块空间,里头能访问外头的 外头不能访问里头的,函数都是闭包,但是用var 定义的变量 就会影响这个闭包,let const 就没事

  • 函数嵌套,内部函数引用外部函数的数据
  • 累加计算
  • 模块封装
  • 异步操作
  • 事件处理:在事件处理中保存状态或数据。通过闭包,可以在事件触发时访问和操作外部变量

12. 跨域(6/20)

在Web开发中,一个网页请求另一个域(域名、协议、端口号任一不同)的资源,就会发生跨域。 浏览器先发送 OPTIONS 预检请求给服务器 服务器在 header 加上 CORS 相关信息返给浏览器 浏览器看看能不能跨域,能就发实际请求,不能就拉倒

// 跨域的代理中转服务器服务
proxy: {
    "/api":{   // /vue代理target
        target: 'http://10.1.XXX.XXX:8088',      // 后端接口的根目录
        // secure: true,   // 如果是 https ,需要开启这个选项,http为false
        changeOrigin: true,    // 是否跨域
        pathRewrite: {     // 是否重写路径,看代理前端路径是否与后端路径一致
          '^/api':'', //将所有含/api路径的,去掉/api转发给服务器                }
    }},

13.宏任务微任务(4/20)

1.js是单线程的语言 2.js代码执行流程:同步执行完==》事件循环同步的任务都执行完了,才会执行事件循环的内容进入事件循环:请求、定时器、事件. 3.事件循环中包含:【微任务、宏任务】 微任务:promise.then 宏任务:setTimeout.. 要执行宏任务的前提是清空了所有的微任务 流程:同步==》事件循环【微任务和宏任务】== 》微任务==》宏任务=》微任务..

14. vue2 vs vue3

【vue3兼容vue2写法】 Vue2:选项式API,面向对象编程的语法 vue3:组合式API,面向函数编程;没有this!!

image.png 在这里插入图片描述


微频

1. == 和 === 的区别

=== :称为等同符,当两边值的类型相同时,直接比较值,若类型不相同,直接返回false; ==:称为等值符,当等号两边的类型相同时,直接比较值是否相等,若不相同,则先转化为类型相同的值,再进行比较;

2. Content-Type请求头的四种常见类型

Content-Type请求头的四种常见类型:multipart/form-data,application/x-www-form-urlencoded,application/json,text/plain application/x-www-form-urlencoded:表单提交 multipart/form-data:上传文件 application/json:JSON串——{'title':'我来了,我是json', 'body' : '我就是json串串'} text/xml:以XML 作为编码方式的进行传输的方式

3.Nullundefined区别

null是表示一个"无"的对象,指向空的对象,这个对象是不存在的,转为数值时为0。null的使用场景:经常用作函数的参数,或作为原型链的终点 undefined是表示一个"无"的原始值,变量被声明了但还没有赋值,就为undefined,转为数值时为NaN

相同点:都是表示值的空缺,所以两者等于(==)是相等的 不同点:null的类型是Object对象,undefined的类型就是Undefiend,所以两者全等(= = =)不相等

4.数据大屏处理分辨率

‌使用transformscale属性进行缩放‌ 考虑使用rem单位进行适配

5.伪类

:link 应用于未被访问过的链接; :hover 应用于鼠标悬停到的元素; :active 应用于被激活的元素; :visited 应用于被访问过的链接,与:link互斥。 :focus 应用于拥有键盘输入焦点的元素。

6.V-if和v-show的区别

  • 展示形式不同 v-if是 创建一个dom节点 v-show 是display:none,block
  • 使用场景不同 初次加载v-if要比v-show好,页面不会做加载盒子 频繁切换v-show要比v-if好,创建和删除的开销太大了,显示和隐藏开销较小

7. var、let、const的区别

1、变量提升:var存在变量提升。letconst没有
2、块级作用域:var没有块级作用域。letconst3、重复声明:var可以重复声明。letconst不可以。
4、修改声明变量:varlet可以,const是常量,不能修改。

8.ES6新增特性

(1) let和const声明变量——let x = 10; // 用let声明的变量x const PI = 3.14; // 用const声明的常量PI (2) 模板字符串——Hello, ${name}! (3) 解构赋值 (4) 箭头函数 (5) Class(类) (6) Modules(模块) (7) Iterators(迭代器)和 Generators(生成器)

9.Js链

原型链:一个实例对象在调用属性和方法的时候,会依次从实例本身、构造函数原型、原型的原型上去查找

  • ‌作用域链‌: 作用域链是为了访问变量而存在的链。它是由作用域组成的一个带头结点的单向链表,主要用来查找变量。当执行代码时,会根据一定的规则形成作用域链,这个链包含了函数内部创建的作用域以及外部的作用域,一直到全局作用域。作用域的分类包括全局作用域、函数作用域(包括ES6引入的块级作用域)和eval作用域。作用域链的概念是JavaScript中变量解析的关键,它决定了变量在哪里被查找以及如何被查找。
  • 原型链‌: 原型链是访问对象的属性而存在的链。每个函数都有一个prototype属性,这个属性指向一个对象,而这个对象就是原型。当访问一个对象的属性时,如果该对象自身没有该属性,那么就会沿着原型链向上查找,直到找到属性或者到达原型链的尽头(即null)。原型链的概念是JavaScript中对象继承的基础,通过原型链,一个对象可以访问到它的原型(即它的构造函数定义的prototype对象)上的属性和方法,从而实现方法的复用和属性的继承。

10.同步发出的请求怎么固定顺序接收返回值

Promise.all()方法允许你并发执行多个异步操作,并在所有操作都完成后按照它们完成的顺序返回结果。这个方法非常适合处理需要按照特定顺序完成的多个异步请求的情况。使用Promise.all(),你可以确保在所有请求都完成时,按照它们开始的顺序接收到返回值。

两个参数 resolve 和 reject,分别对映成功回调和失败回调 Promise 内部有 3 种状态 pending(进行时),fulfilled(已成功),rejected(已失败)。且这三种状态是不可逆的 为了更好的控制下一步执行,又诞生了三个实例方法 then、catch、finally。then 方法一般接受两个参数 resolve、reject

Any任意一个成功 Race:任意不管成功失败 allSettled:所有的都有结果不管成功失败 All:全部成功

11.JSON数据类型

字符串、数字、布尔、空值、数组、对象 判断数据类型:typeOf instanceOf Object.prototype.toString.call()

12. 箭头函数和普通函数有什么区别

箭头函数的语法相对于普通函数更加简洁。箭头函数可以使用箭头(=>)来定义,省略了function关键字和花括号,可以直接定义函数的参数和返回值 this指向的不同 不适用于构造函数

13. 一行三列 11个元素怎么靠左布局

父:display: flex; flex-wrap: wrap;
子:flex: 0 0 calc((100% - 10px)/3);

14. Foreachmap区别

map有返回值而且必须return返回一个数组才行 ; 而forEach没有返回值可直接打印结果

15. This指什么?(一直还是不太理解)

默认情况下,‌this指向全局对象。 ‌在非严格模式下,‌函数中的this默认指向全局对象。‌ 在严格模式下,‌函数中的this是undefined。‌ 在箭头函数中,‌this保留封闭词法上下文的this。‌ 在对象方法中,‌this指向调用该方法的对象。‌ 在构造函数调用中,‌this绑定到正在构造的新对象。‌ 在事件处理程序中,‌this绑定到放置侦听器的元素。

在组件中代表当前组件的对象‌

16. computed vs watch vs watchEffect

(1)watch是Vue中一个非常强大的特性,它允许你监听数据的变化并做出相应的反应。它有两种用法:一是监听一个具体的数据变化,二是监听多个数据的变化。 (2)computed用于计算派生数据。它依赖于其他响应式数据,并且只有在相关数据发生变化时才会重新计算。 (3)watchEffect()函数用于创建一个自动追踪依赖的响应式副作用。它会在初始化时会立即执行一次,并自动追踪在回调函数中使用的所有响应式数据,在这些数据发生变化时重新运行回调函数。

image.png

image.png

17. vue哈希路由

Vue Router使用哈希模式(hash mode)来创建前端路由,这意味着URL中的#符号后面跟着的部分就是当前的路由。 例如,如果你有一个路由/about,在哈希模式下,它可能会被表示成#/about 在这种模式下,路由的变化不会触发页面的刷新,所有的路由改变都在客户端进行。

  • 优点:在使用哈希模式时,不需要服务器端配置特殊的路由规则,可以方便地在静态服务器上部署和使用。
  • 缺点:URL中的哈希符号可能被视为页面的片段标识,不适合搜索引擎优化(SEO)和某些网站分析工具。 在这里插入图片描述

18. vue数据双向绑定原理

Vue的数据绑定是通过响应式系统实现的。简单来说,Vue会用Object.defineProperty来监听数据的变化,一旦数据变化,视图会自动更新

19.组件data为什么是一个函数

1、防止data复用; 2、data独立性; 3、作用域; 4、js的特性。 总结来说,如果data是一个函数的话,这样每复用一次组件,就会返回一份新的data(类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据)。

20.http状态码

  • 1xx(信息性状态码):表示接收的请求正在处理。
  • 2xx(成功状态码):表示请求正常处理完毕。
  • 3xx(重定向状态码):需要后续操作才能完成这一请求。
  • 4xx(客户端错误状态码):表示请求包含语法错误或无法完成。
  • 5xx(服务器错误状态码):服务器在处理请求的过程中发生了错误。
  • 100(继续):服务器已经接收到请求的一部分,客户端可以继续发送剩余的请求。
  • 200(成功):请求已成功处理,并返回所请求的资源。
  • 201(已创建):请求已成功处理,并在服务器上创建了新的资源。
  • 204(无内容):服务器成功处理了请求,但没有返回任何内容。
  • 301(永久重定向):请求的资源已经被永久移动到新的URL。
  • 302(临时重定向):请求的资源暂时被移动到新的URL。
  • 304(未修改):客户端发送了一个条件请求,服务器判断资源未发生变化,返回此状态码。
  • 400(错误请求):服务器无法理解请求的语法。
  • 401(未授权):请求需要身份验证。
  • 403(禁止):服务器拒绝请求访问。
  • 404(未找到):服务器找不到请求的资源。
  • 500(服务器内部错误):服务器在执行请求时发生了错误。
  • 502(错误网关):服务器作为网关或代理,从上游服务器接收到无效的响应。
  • 503(服务不可用):服务器暂时无法处理请求,通常是由于过载或维护。

21.get vs post

最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。

  • GET:由于参数暴露在 URL 中,可能会被恶意用户通过网络抓包工具等获取,因此不适合传递敏感信息,如密码等。GET 请求更适合用于获取公开信息。
  • POST:参数在请求体中发送,相对于 GET 请求更安全,适合传递敏感信息,如登录表单的用户名和密码等。
  • GET:请求结果可以被缓存,可以被浏览器缓存、代理服务器缓存等,如果请求相同的 URL,可以直接使用缓存结果,提高性能。
  • POST:请求结果通常不会被缓存,每次请求都会向服务器发送数据,不会使用缓存结果。
  • GET:由于 GET 请求是幂等的,多次执行相同的 GET 请求应该返回相同的结果,不会对服务器端的数据产生影响,因此适合用于查询操作。
  • POST:POST 请求不是幂等的,多次执行相同的 POST 请求可能会产生不同的结果,可能会对服务器端的数据产生影响,因此适合用于对数据进行修改或者创建新的资源。

22.怎么阻止冒泡和浏览器的默认事件

阻止事件冒泡‌:使用event.stopPropagation()方法。 阻止浏览器的默认行为‌:使用event.preventDefault()方法

23.Css盒模型

在HTML页面中的所有元素都可以看成是一个盒子 盒子的组成:

内容content、内边距padding、边框border、外边距margin盒模型的类型
  • 标准盒模型 margin I border + padding + content
  • IE盒模型 margin + content(border + padding)
  • 控制盒模型的模式:box-sizing:content-box(默认值,标准盒模型)、border-box(IE盒模型);

24.CSS选择器优先级

[!important ·>行内样式·>id >·类/伪类/属性·>标签·>全局选择器

25.伪元素

::after p::after 在每个 <p> 元素之后插入内容。 ::before p::before 在每个 <p> 元素之前插入内容。 ::first-letter p::first-letter 选择每个 <p> 元素的首字母。 ::first-line p::first-line 选择每个 <p> 元素的首行。 ::selection p::selection 选择用户选择的元素部分。

其他扩展

MySQL常用语句

  • 数据库操作‌
创建数据库:CREATE DATABASE database_name;
删除数据库:DROP DATABASE database_name;
选择数据库:USE database_name;
  • 表操作‌
创建表:CREATE TABLE table_name (column1 datatype, column2 datatype, ...);
删除表:DROP TABLE table_name;
查看表结构:DESC table_name; 或 SHOW COLUMNS FROM table_name;
‌数据操作‌
插入数据:INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);
更新数据:UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;
删除数据:DELETE FROM table_name WHERE condition;
查询数据:SELECT column1, column2, ... FROM table_name WHERE condition;
  • 其他常用语句‌
显示所有数据库:SHOW DATABASES;
显示当前数据库中的所有表:SHOW TABLES;
显示表中的所有记录:SELECT * FROM table_name;
显示创建表的SQL语句:SHOW CREATE TABLE table_name;