2025前端面试题汇总

450 阅读5分钟

一:JavaScript

1、闭包是什么?利弊?如何解决弊端?

闭包是什么:JS中内层函数可以访问外层函数的变量,外层函数无法操作内存函数的变量的特性。我们把这个特性称作闭包。

闭包的好处

  • 隔离作用域,保护私有变量;有了闭包才有局部变量,要不然都是全局变量了。
  • 让我们可以使用回调,操作其他函数内部;
  • 变量长期驻扎在内存中,不会被内存回收机制回收,即延长变量的生命周期;

闭包的弊端:内层函数引用外层函数变量,内层函数占用内存。如果不释放内存,过多时,易引起内存泄露。

解决办法:无法自动销户,就及时手动回收,使用后将函数的引用赋null。

2、深度拷贝

1、JSON的stringify和parse处理的缺点?

  • 如果对象中有属性是function或者undefined,处理后会被过滤掉;
  • 如果属性值是对象,且由构造函数生成的实例对象,会丢弃对象的constructor

2、$.extend()

使用jquey的extend方法不仅能实现深度拷贝,还能实现深度合并。具体用法

深度拷贝:$.extend({},targetObject) // targetObject是需要复制的对象

深度合并:$.extend(true,{},targetObject1,targetObject2) // 可以将两个对象深度合并后再返回出一个新对象

3、判断空对象

1、用JSON的stringify和parse转成字符串后,跟'{}'对比;

2、用ES6,判断Object.keys(targetObject)返回值数组的长度是否为0;

3、用ES5,判断Object.getOwnPropertyNames(targetObject)返回的数组长度是否为0;

4、如何改变this指向?

  • call/apply

    let a = { name: 'sunq', fn:function(action){ console.log(this.name + ' love ' + action); } } let b = {name:'sunLi'}

    // 正常的this指向 a.fn('basketball'); // sunq love basketball // 改变this指向,并体现call与apply的区别 a.fn.apply(b,['football']); // sunLi love football a.fn.call(b,'football'); // sunLi love football

  • bind

    // 还是上面的示例,bind也可以实现call和apply的效果。 // bind的不同之处在于bind会返回一个新的函数。如果需要传参,需要再调用该函数并传参 a.fn.bind(b)('piano'); // sunLi love piano

5、沙箱隔离怎么做?

使用iframe可以实现,变量隔离

二:CSS

1、如何实现一个宽度不固定的上下左右居中的弹框?

方法一:
.pop{
    width: 300px;
    height: 300px;
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    border: 1px solid red;
} 

方法二:
.chartLengend {   // 父元素
    width: 60px;
    height: 40px;
    position: relative;
    .line {       // 子元素
      width: 100%; 
      height: 3px;
      background-color: #DEA182;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      border-radius: 2px;
    }
}

三:Vue

1、单页面应用是什么?优缺点?如何弥补缺点

单页面对一个入口DOM通过路由去更改内容,整个应用只有一个html页面

SPA优点:用户体验好,没有页面切换就没有白屏情况;

SPA缺点:首屏加载慢,不利于SEO

SPA弥补:通过压缩、路由懒加载缓解首屏慢;通过SSR 服务器端渲染解决SEO问题;

2、组件间通信方式常用哪些?

父子:props和$emit

兄弟:使用EventBus(事件总线),vue.$bus.on和emit方法。详情

3、v-if和v-show区别?

v-if控制Dom是否存在,v-show控制样式

4、vuex是什么?使用步骤大概说下

vuex是一个状态管理工具,集中式的管理所有组件的状态数据。统一的去管理组件,将组件的状态抽象为一个store文件,通过commit方法触发mutation里的函数来改变组件属性。

组件中可以使用computed属性监听数据的变化控制组件显隐等。如下举个loading组件的栗子

loading组件中根据Loading数据,控制DOM显隐

<template>
    <div class="cover" v-show="Loading">
        <div>加载中</div>
    </div>        
</template>
 
<script>
  import Store from '../../store'
  export default {
    name: "Loading",
    computed:{
      Loading(){
        return Store.state.Loading; 
      }
    }
  }
</script>

vuex集中管理状态,创建一个叫store的js文件

import Vuex from 'vuex';
Vue.use(Vuex);
 
export default new Vuex.Store({
  state: {
    // Loading组件
    Loading:false,
  },
  mutations: {
    // Loading组件
    ChangeLoading:function (State,Value) {
      State.Loading = Value;
    }
  },
});

使用loading的组件中,这样操作

import Store from '../../store'
Store.commit("changeFooter",true);

5、vue watch和computed区别?

computed

计算结果并返回,只有当被计算的属性发生改变时才会触发(即:计算属性的结果会被缓存,除非依赖的响应属性变化才会重新及孙)

watch

监听某一个值,当被监听的值发生变化时,执行相关操作。

与computed的区别是,watch更加适用于监听某一个值得变化,并做对应操作,比如请求后台接口等。而computed适用于计算已有的值并返回结果。 监听简单数据类型:

data(){      
    return{        
        'first':2     
    }   
},   
 watch:{      
     first(){        
         console.log(this.first)    
    }   
 },

6、Vue的虚拟Dom是什么?

7、讲一讲对vue的双向绑定原理的认识?

双向绑定主要指修改数据时,无须操作DOM,视图会自动刷新。操作视图时绑定的数据也会跟随变动。

  • 数据 => 视图

vue在初始化实例时,会用Object.defineProperty方法,给所有的数据添加setter函数,实现对数据变更的监听。当数据被修改时,生成新的虚拟DOM树,跟老的虚拟DOM对比,根据对比结果找出需要更新的节点进行更新。

  • 视图 => 数据

从视图到数据较为简单,视图变化后触发监听如oninput等,在绑定的方法中修改数据。

8、vue首屏优化怎么做?

1、vue-cli开启打包压缩 和后台配合 gzip访问;

2、路由懒加载;

9、vue2的缺陷是什么?如何解决vue2.0数组中某一项改变,页面不改变的情况?

缺陷:数据如果为对象直接新增属性,如果为数组通过下标操作数组项,页面无法触发更新。

原因: Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。关于数组作者通过重写push/pop/shift/unshift/splice/reverse/sort这些方法来实现数据的相应绑定,其余的操作无法触发页面更新;

对策:关于对象可以通过Vue.set(obj,key,value),组件中通过this.set(obj,key,value),组件中通过this.set(obj,key,value)实现新增,修改属性vue可以相应更新视图。关于数组也可以通过Vue.$set(obj,key,value),或者作者重写的那些方法来操作;

10、异步操作放在created还是mouted?

如果有些数据需要在初始化时就渲染的,比如select下拉框的下拉内容,在mouted中请求。好处如下

  • 页面初始化速度更快,减少用户等待时间
  • 放在 created 中有助于一致性,因为ssr 不支持 beforeMount 、mounted 钩子函数

四:ES6

1、箭头函数与es5函数区别?

  • 箭头函数的this指向是固定的,普通的this指向是可变的

    let a = { name: 'sunq', fn:function(action){ console.log(this.name + ' love ' + action); } } let b = {name:'sunLi'}

    // 正常的this指向调用他的对象 a.fn('basketball'); // sunq love basketball // 改变this指向 a.fn.apply(b,['football']); // sunLi love football

    // 如果将a对象的fn函数改成箭头函数,this.name会是undefined // 箭头函数的this指向不会改变,且总是指向函数定义生效时所在的对象。

  • 不可以当作构造函数,不可以对箭头函数使用new命令,否则会抛出一个错误。

    var Person = function(name){ this.name = name; } let sunq = new Person('sq'); // {name: 'sq'}

    var Person = (name) => { this.name = name; } let sunq = new Person('sq'); // 报错 Person is not a constructor

  • arguments对象

  • 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

2、ES6提供的解决异步交互的新方法?区别?

Promise、Genarate、async\await

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

4、先并行请求2个接口后,再请求第3个接口,如何处理?

使用Promise.all()方法,将两个promise传入all方法,拿到异步结果再请求第三个

明明知道的语法,面试官一问我偏偏就是跟实际场景联系不到一块,具体代码

五:ElementUI

1、如果需要修改样式怎么做?

  • 再写一个样式表引入,!important覆盖
  • 样式穿透

六:Jquery

关于Jquery,提问的机率不高。但是如果你简历上写的工作经验都是Jquery,很可能就会被问了。我就是因为这个原因被问的下面的问题

1、如何获取同一个cl下,最后一个li?

2、window.load和$(document).ready()的区别?执行先后顺序?

3、如何绑定一个点击事件?

4、Jquery常用动画?

七:Git的使用

1、常用哪些语句?

pull、commit、push、reset、merge、log、branch、

2、版本回退语句?soft和hard区别?

git reset --soft 版本号

git reset --hard 版本号

soft会退后,代码改动在本地还保存的有。hard会删除本地改动,彻底抹去该版本的痕迹。详情

3、合并分支注意事项?

将自己分支合到目标分支前,最好先将目标分支合到自己分支上处理完冲突,再将自己的分支合回目标分支。

八:敏捷开发

1、什么是敏捷开发?

个人理解,敏捷开发就是把一个大需求拆为多个独立的小需求。每个小需求可独立开发、测试、上线,循序渐进的完成整个系统。每个版本的周期可能比较短,比如2周,或者4周。

比如某公司需要开发维护一个巨大的平台,可能把平台外包给多个公司干。如果用如上方法,并行开发,可显著缩减工期。

如果想要保证每个版本又快又顺利的上线,需要有完善的角色支持和流程规范。

2、敏捷开发的好处?

个人理解,当团队稍大,工期很紧时,如何有条不紊的保证版本质量就需要一套有效的流程了。

比如一个团队同时收到3个需求,每个需求分发给多个前后端开发。作为版本负责人或者项目负责人,如何把控每个人的代码质量、完成进度、过程留痕、风险规避,其实是有难度的。

一个需求如果经过,需求澄清、方案设计、设计评审、需求传递、版本排期/评审、开发划分、版本开发、测试用例评审、内部测试、代码评审、灰度试用&测试、版本发布、业务验收等完整的流程,可以有效地降低犯错的几率。也方便后期的查找责任人,总结各环节的问题,提升团队的工作效率,使交付越来越平稳。

九:开源项目

部分公司面试要求中有写,维护有开源项目且具有50个star者优先。

我有一个开源个人网站,200多个star,分享给大家:CodingLife

面试过程中无话可说时,可以拿出来聊聊,缓解尴尬。

博客的代码全部开源:源码Github地址