前端面试题汇总学习

本文详细列举了前端开发中常见的知识点,包括闭包、Promise的使用、JavaScript原型和原型链、事件循环机制EventLoop以及Vue的响应式原理。还介绍了Vue组件、生命周期、MVVM模式、Diff算法、Vue2与Vue3的区别以及浏览器渲染过程等。此外,涵盖了面试中可能遇到的业务问题,如表格生成、拖拽复制、主题切换等。

文章目录

知识点

一、闭包

闭包是能够读取其他函数内部变量的函数。本质上,闭包就是将内部函数与外部函数链接在一起的一座桥梁。

  • 产生条件:嵌套的函数,内部函数引用外部函数的数据
  • 作用:1.读取内部函数的变量 2.让这些变量一直保存在内存中 3.避免使用全局变量,防止全局变量污染
  • 注意点:闭包会使变量保存在内存中,内存消耗很大,所以不能滥用闭包,否则会影响性能。
二、Promise

promise对象用于表示一个异步操作的最终完成(或失败)及其结果值

  • promise,简单来说就是一个容器,里面保存着某个未来才会结束的事件的结果,通常是一个异步操作。
  • 从字面上理解,promise是承诺、允诺的意思,意思是使用promise后,不管成功还是失败肯定会有返回值。
  • promise有三个状态:pending(进行中)、resolved(完成)、rejected(失败)
  • promise新建后就会立即执行
  • promise.all()用于将多个promise实例,包装成一个新的Promise实例
  • 使用场景:异步加载图片、请求超时提醒、接口重试实现(刷新token)、同时拉取多个接口,将多个请求结果合并到一起(微信小程序登录)
1.Promise 解决地狱回调的问题
  • 回调地域,简单来说就是异步回调函数的嵌套,存在异步任务的代码,不一定能按照其顺序正常执行
  • 解决回调地域的办法是,利用promise.then方法将异步操作的结果按照顺序执行,catch方法用来接收处理失败时相应的数据。在上一个promise.then方法中,返回下一个promise对象
//1.封装一个函数 :  根据文件名生成  文件读取的promise
function getPromise(fileName) {
    let p = new Promise((resolve, reject) => {
        //读文件
        fs.readFile(`./data/${fileName}.txt`, 'utf-8', (err, data) => {
            if (err == null) {
                //成功
                resolve(data);
            } else {
                //失败
                reject(err);
            }
        });
    });
    return p;
};

//2.解决需求: 要先读a, 读完a后读b, 读完b后读c.

//开始读取a
getPromise('a').then((data)=>{
    console.log(data);
    //继续读取b
    return getPromise('b');
}).then((data)=>{
    console.log(data);
    //继续读取c
    return getPromise('c');
}).then((data)=>{
    console.log(data);
}).catch((err)=>{
    //以上三个异步操作,只要有任何一个出错,都会执行err
    console.log(err);
});
2.async/await

async用于声明一个函数是异步的,而await则可以认为是async await的简写形式,是等待一个异步方法执行完成的。函数返回值是一个全新的promise

promise和async/await都是解决异步编程的一种方式,但是async和await使得异步代码看起来像同步代码

三、JavaScript原型、原型链
  • 我们创建的每个函数都有一个prototype(原型)属性,prototype属性指向原型对象。通过该函数创建的实例对象会共享原型对象上的所有属性和方法
  • 每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们去访问一个对象的属性时,如果这个对象内部不存在这个属性,那么就会到他的prototype原型上找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,这就是原型链的概念
四、事件循环机制(Event loop)

Js是单线程的,被放入事件队列不会立即执行其回调,而是等待当前执行栈中的所有任务都执行完毕,主线程处于空闲状态时,主线程会去查找事件队列是否有任务。如果有,主线程会从中取出排在第一位的事件,并把这个事件对应的回调放在执行栈中,然后执行其中的同步代码,如此反复就称为事件循环(Event Loop)

五、变量回收机制

全局变量不会被回收。局部变量会被回收,也就是函数一旦执行完毕,函数内部的东西就会被销毁,只有被另一个作用域所引用的变量不会被回收(闭包)

六、vue2响应式原理

在data初始化时,vue将遍历此对象所有property,并使用Object.defineProperty把这些property全部转换成getter和setter,同时实例化一个Dep。视图渲染时,getter触发,Dep会收集Watcher更新视图。watcher在组件挂载时实例化,watcher与组件一一对应

vue双向数据绑定原理

vue.js则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的getter、setter,在数据变动的时候发布消息给订阅者,触发相应的回调

七、vue2组件、生命周期、监听器
  • 组件是可复用的vue实例,所以它们与new Vue接收相同的选项,data、computed、watch、methods以及生命周期钩子等

生命周期

  • beforeCreate: 创建前,vue实例创建时触发,一般不做操作
  • created:创建后,挂载数据,绑定事件等
  • beforeMount:挂在到页面前,已经创建虚拟Dom,准备渲染
  • mounted:挂载到页面后,已经渲染真实dom
  • beforeUpdate:更新页面前
  • updated:更新页面后
  • beforeDestory:销毁实例前
  • destroyed:销毁后

computed与watch

  • computed:属性的结果会被缓存,除非依赖的响应式属性发生变化才会重新计算,主要当作属性来使用,专注于结果
  • watch:一个对象,键是需要观察的表达式,值是对应的回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,专注于过程
八、mvvm
  • MVVM实际上就是MVC的升级,model:模型,本质上就是数据对象data。view:视图,模板页面。ViewModel:视图模型,本质上就是vue的实例。
  • vm是MVVM思想的核心,vm视图模型其实是model和view之间的一个调度者,当model中的数据变化,vm数据绑定,将页面相关的值进行更新,当view视图中的数据发生变化,vue通过Dom监听对model中的数据进行更新
九、keep-alive
  • 将组件进行持久化,使组件的状态维持不变,在下一次展示时也不会进行重新初始化组件
  • vue内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染
十、diff算法
  • 笼统的理解就是:新旧虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后根据记录去局部更新Dom
  • diff算法就是在虚拟Dom树从上至下进行同级比较,如果上层已经不一致,下面的Dom就全部重新渲染。这样的好处就是算法简单,减少对比的次数
  • 特点1:只会同级比较,不会跨级
  • 特点2:在diff比较的过程中,循环从两边向中间比较
十一、vue3特性
  • Composition-api:我们可以把实现一种功能的代码写在一起,甚至还可以把它们单独抽取在一个js文件或者一个函数中。在js文件中也可以引用Composition-api的生命周期函数。这将极大的提高代码的可维护性。这样就可以更好的提取和重用多个组件之间的逻辑。
  • setup函数中无法使用this获取组件实例
  • vue2.x中,一个组件只能有一个根节点,在vue3.0中,去掉了能有一个根节点的限制。这个改动能够很大的优化html文档结构。
十二、vue3响应式
十三、vue2、vue3区别
十四、二分查找

使用二分查找的前提是,目标数组的元素必须是有序排列的。从数组的中间节点开始查找,将数组分为两部分,将目标值和中间节点元素对比,确定查找前半部分还是后半部分

十五、浏览器渲染过程
  • 解析HTML生成Dom树
  • 解析css生成css树
  • 将Dom树和css树结合生成渲染树
  • 遍历渲染树开始布局,计算每个元素的大小和位置
  • 将渲染树的每个节点渲染到屏幕上
十六、scss用过哪些功能
  • scss嵌套、父选择器嵌套 (&)
  • 自定义函数(@function 使用@return返回 )
  • @each、@if等控制指令
  • 占位符等选择器
  • 定义常量
  • 混合mixins
@mixin left {
  float: left;
  margin-left: 10px;
}
// 在使用时 需要调用`@incluede`
div {
    @include left;
}
  • 继承(@extend)
// 选择器可继承另一个选择器   @extend   class2将具备class1+class2的属性
.class1 {
    border: 1px solid #ddd;
}
.class2 {
     @extend .class1;
     font-size:120%;
}
十七、怪异模式下 100* 100,padding为50的盒子显示的宽高为多少

盒子模型分为怪异模式和标准模式,标准模式的盒子会被padding撑开,而怪异模式则相当于将盒子的大小固定好,再将内容装入盒子,并不会被padding所撑开

.box{
   box-sizing: border-box; // 不添加则按照标准模式,添加后则是怪异模式
}

在这里插入图片描述

十八、npm run dev执行过程,把你知道的说说

首先,当我们使用npm来管理项目的时候,会生成一个package.json文件。npm run dev是执行在package.json中的配置,根据配置可以在node_modules中的.bin文件夹下找到对应的可执行的脚本,执行实现对应的操作。

十九、引用文件时经常用到的@符,一般指向的是哪,比如@component/xx.vue

@是webpack设置的路径别名,代表什么路径,要看webpack的build文件夹下webpack.base.conf.js里面对于@是如何配置,默认是指向根目录src文件夹

二十、html中写css和js对页面渲染有什么影响

我们一般的书写形式是Css在上方,接着HTML,最后写的是JS

影响

  • Css: Css不会阻止Dom树的解析,但是会阻止Dom树的渲染,Css加载会阻塞后面的JS语句的执行
  • JS: JS会阻止Dom树的解析和渲染
二十一、vue、react异同

在这里插入图片描述
参考:https://blog.csdn.net/sinat_17775997/article/details/115482179

二十二、Es6有哪些常用的功能
  • let/const
  • 解构赋值
  • 扩展运算符(…)
  • 反引号表达式
  • Promise对象
  • 箭头函数
  • async和await函数
  • Set()数据结构
二十三、vue router有哪些钩子(不是生命周期)
  • beforeEach
  • beforeResolve
  • afterEach
  • beforeEnter
  • beforeRouterEnter
  • beforeRouterUpdate
  • beforeRouterLeave
二十四、vuex包括哪些模块

vue主要解决的是,在复杂的组件关系中,组件之间的数据如何更加便捷的进行传递

  • state
  • mutations
  • actions
  • modules
  • getters
二十五、组件如何传值
  • 父传子:props
  • 子传父:定义事件,使用this.$emit(事件)
  • vuex
  • $attr + l i s t e n e r (简单来说: listener(简单来说: listener(简单来说:attrs和 l i s t e n e r 就是两个对象, listener就是两个对象, listener就是两个对象,attrs中存放的是父组件中的非props属性,$listener里存放的是父组件中绑定的非原生事件)
  • provide和inject
  • 本地缓存也可以实现
二十六、vue中父子组件渲染,生命周期的过程会怎样显示

父子组件的生命周期的执行顺序是从外到内,再从内到外的

1
更新流程
父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated

销毁流程
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed

二十七、跨域怎么做
  • jsonp:利用<script>标签不受同源策略限制的特性
  • cors
  • nginx代理
  • node中间件代理
  • script标签
二十八、项目中怎么用vuex的
  • 首先,安装vuex依赖
  • 在目录下新建store文件夹,存放vuex相关的操作
  • index.js负责引入不同模块的vuex,导出
  • 新建modules文件夹,存放不同模块的vuex
  • 在各个模块中定义state、getters、mutations
二十九、http有哪些缓存
  • 客户端缓存、浏览器缓存(私有的,不会与其他浏览器共享)
  • 网关缓存(共享缓存,位于服务器端)
  • 代理缓存
三十、连续调三个接口,ab接口调完之后再调用c接口,你会怎么做

a,b接口使用promise对象,然后使用promise.all()传入a,b两个promise对象,待执行返回a,b接口的结果,然后再执行c接口

三十一、接口是如何封装的

封装通用的请求方法,header信息,对请求结果异常做统一处理。然后请求的具体路径、方法、参数等信息动态传入,

三十二、小程序有没有大小限制?如果超出限制怎么做?

小程序的大小有限制(2M),当主包大小超出后,可以进行分包,分包大小不能超过2M,整个小程序可以达到8M

优点:小程序太大,首次打开小程序的时候会比较慢,可以进行分包处理,按需下载资源

三十三、vue style scoped 属性作用是啥,知道原理吗

作用:实现组件的私有化,不对全局造成样式污染,标识当前style属性只属于当前模块
原理:打包之后,编译成特定样式,data-v-[hash],即CSS带属性选择器

三十四、token失效刷新如何实现的,token和登录的处理

当接口请求返回token过期code,将需要执行的接口缓存到一个队列中,然后调用刷新token的接口,token刷新后,一次执行缓存队列中的接口,执行完毕后,清空队列

// 将需要重新执行的接口缓存到一个队列中
addSubscriber(() => {
    request({
        url: params.url,
        params: params.params,
        methods: params.methods,
        contentType: params.contentType,
        callback: resolve
    })
})
三十五、性能优化
  • 减少请求数量
    • 雪碧图
    • 使用字体图标(iconfront)代替图片
    • 使用缓存
  • 减小资源大小
    • js、css、html压缩
    • 图片压缩
  • 优化资源加载:CDN加速、预加载
  • 减少重绘和回流(减少Dom操作)
  • webpack性能优化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GFnpQhDd-1678764628488)(en-resource://database/4559:1)]

三十六、重排(reflow)重绘(repaint)

重排 : 浏览器需要重新构造渲染树,这个过程称之为重排,也称为回流

  • a.添加或删除可见的 DOM 元素
  • b.元素位置、尺寸、内容、元素本身改变
  • c.浏览器窗口尺寸改变

重绘 : 浏览器将受到影响的部分重新绘制在屏幕上 的过程称为重绘(如:改变颜色只会引起重绘)

如何减少重排重绘?

  • a.当在逻辑中修改元素的样式的时候,不要直接修改样式,可以通过class来控制样式
  • b.如果要对Dom元素进行一系列的操作,可以将元素先设置display:none,脱离文档流,之后再设置回来
三十七、从浏览器地址栏输入URL后发生了什么
  • DNS域名解析地址,发送请求
  • 服务器后台处理返回数据,浏览器接收文件
  • 浏览器对加载到的资源(HTML、JS、CSS)进行语法解析,建立相应的Dom
  • 载入资源文件,渲染页面
三十八、webpack了解过吗
  • webpack是一个模块打包工具,可以使用webpack管理你的模块依赖,并编译输出模块们所需要的静态文件。它能很好的管理和打包项目中用的的HTML、JS、CSS以及各种静态文件,让开发更高效。webpack模块打包器会分析模块间的依赖关系,最后生成优化且合并后的静态资源
三十九、this的指向

根据函数的调用方式的不同,this会指向不同的对象

  • 以函数的形式调用时,this指向window(全局函数)
  • 以方法的形式调用,this指向调用方法的那个对象(对象的方法)
  • 以构造函数的形式调用时,this指向实例对象
  • 以时间绑定函数的形式调用时,this指向绑定事件的对象
  • 使用call、bind、apply调用时,this指向指定的那个对象
四十、谈谈盒子模型

content+padding+border+margin,通过设置box-sizing:border-box;区分以下两个模型

  • 标准盒子模型(content+padding+border+margin)
  • 怪异盒子模型(固定盒子大小往里塞)
四十一、什么是BFC

块级格式化上下文,是W3C规范中的一个概念,是指浏览器中创建一个独立的渲染区域(BFC可以理解为一个封闭的大箱子,箱子中的元素不会在布局上影响到外面的元素),并拥有一套渲染规则,它决定了子元素如何定位,以及与其他元素的相互关系和作用

四十二、请描述一下ES6的class

通过class关键字可以定义类,写法更加清晰、更像面向对象编程

四十三、知道lodash吗?它有哪些常见的API

一个JavaScript库。lodash是对各种函数、方法的封装,使得使用起来更方便

  • 深拷贝(Json.parse(Json.stringify() / Object.create() / 递归实现)
  • 对象比较
  • 数组去重
  • 数组过滤
四十四、你平时用什么工具进行打包?babel是什么
  • webpack进行打包,打包js、css、html、图片等,它可以分析整个文件之间的依赖,将文件合并、压缩,生成最终项目文件
  • babel是一个JS编译器,将ES6/ES7等语法转换成ES5语法(将浏览器不认识的语法编译成浏览器可以识别的语法),从而能够在大部分浏览器中运行
四十五、图片的懒加载实现

页面包含大量的图片时,如何首页面的所有图片一次性全部加载完,用户的体验会很差,目前流行的是滚动动态加载,也就是懒加载,显示在屏幕之外的图片默认不加载,随着页面的滚动,图片进入了显示的范围,则触发图片的加载显示

四十四、常见的布局方式及其优缺点
  • grid(网格)布局
  • flex布局
  • 浮动
  • 绝对定位
四十四、防抖、节流及其应用场景
1.防抖

在事件触发指定时间之后,再去真正的执行函数,如果在该时间之内又发生了该事件,则重新计时,(对于短时间内连续触发的事件,防抖的含义就是让某个时间期限内,只执行一次

应用场景

  • 滚动事件触发(实时输出距离顶部的距离,显示返回顶部按钮)
  • 搜索框的输入查询
  • 表单验证
  • 按钮的提交事件
  • 浏览器的窗口缩放
  • 页面resize事件(常见于需要做页面适配的时候,需要根据最终呈现的页面情况进行dom渲染)
2.节流

在防抖的基础上,如果在规定时间内一直触发,理论上一直不会触发,所以要实现就算一直触发,也要在规定时间后触发一次

应用场景

  • 搜索框的实时搜索事件
四十五、releative,absolute,fixed作用,及相对于什么定位的
四十六、原生JS的方式给一个按钮绑定两个onclick事件
<div id="btn">我是按钮</div>

<script>
    var btn = document.getElementById('btn');
    btn.addEventListener( 'click', one );
    btn.addEventListener( 'click', two );
    
    function one(){
        console.log( 'one' )
    }
    
    function two(){
        console.log( 'two' )
    }
</script>

业务问题

一、画布中如何在鼠标点击的位置生成table,在vue项目中如何实现,点击一下生成一个table
  • 在画布上添加点击监听事件,结合绑定事件,获取坐标
  • v-for遍历生成table,点击的时候像数组中push一个数组即可
<div id="canvas" width="" height=""></div>

 var c = document.getElementById('canvas')
    var ctx = c.getContext('2d')
    c.addEventListener('click', function (event){
        var rect = c.getBoundingClientRect()
        var x = xxx
        var y = xxx
    })
二、生成的table可以拖拽,并在鼠标放下时复制,怎样复制table组件,提供个思路

在这里插入图片描述

三、 table左上角有角标,如何实现

使用css将图形画出来,并将图形定位到具体位置

在这里插入图片描述

::v-deep table th.star::after {
  content: '';
  box-sizing: border-box;
  position: absolute;
  right: 0;
  top: 0;
  border-right: 4px solid red;
  border-top: 4px solid red;
  border-left: 4px solid transparent;
  border-bottom: 4px solid transparent;
  width: 0;
  height: 0;
}
四、如何实现用户下拉选择主题,选择后网站整体换肤
  • css样式覆盖:准备多套css样式表文件,在下拉框的选项中给出能对应样式表文件的key,用户选择选项后,将对应的css文件渲染上去即可
  • css变量方式
五、坦克大战子弹打中砖块消失,设计思路有考虑过吗

首先,坦克大战的地图应该是根据数组值渲染绘制各种元素,坦克和砖块均是,其次,当坦克的子弹发出,沿着运行轨迹运行,当运行到砖块的下标,子弹和砖块碰撞,销毁砖块,绘制轨道

六、elementUI中,日期组件,一个日期弹窗选择三段时间,如何实现,比如规定用户选择10.1-10.7,10.11-10.14,10.18-10.20

在ElementUI日期组件进行二次封装,UI显示三段日期,选择第一段时间之后存储,继续点击选择第二段时间,次之

  • 二次封装的注意点
  • 组件继承二次封装原有的属性、方法、插槽
  • 属性:v-bind=“$attrs”
  • 方法:v-on=“$listeners”
  • 插槽
<template v-for="(index,name) in $slots" :slot="name">
    <slot :name="name" />
</template>
七、下拉选择组件用户选择 label,后台传入id,在vue中如何实现更优雅
八、项目中遇到哪些难点

TODO

九、封装过哪些组件
  • 二次封装Element
  • 文件上传
  • 小程序分享
  • canvas海报
十、项目中如何鉴权的,即用户登录以后会发生什么
  • web端菜单采用动态路由的方式解决,当用户登陆后,根据用户路由动态的渲染路由
  • 获取用户的权限路由,将用户权限存储在状态管理中,页面中的具体操作,注册全局指令,传入相应的操作标识符,根据用户的权限是否包含,实现控制显示
十一、前端登录的密码向后端发送请求有做什么处理吗
  • 对密码进行加密,提高安全性
十二、组件封装原则
  • 通用性:组件开发要服务于业务,为了更好的抽离,又要从业务中抽离
  • 单一职责:对于有多个功能的组件,应该转换成多个小组件,组合而成
  • 扁平化:给组件传递props时,建议用扁平化的props,而不是用嵌套的对象或者数组
  • 扩展性:预留插槽,提高组件的扩展性,适应不同的业务场景
十三、能自己搭建框架吗

TODO

十四、后台主动推消息给你(前台),如何实现

webSocket实现, …

  • 聊天应用
  • 多人游戏
  • 股票交易和金融应用
  • 文档合作编辑
  • 社交应用

1.java后端如何主动发数据到前端_使用websocket实现后台主动推送数据至前端,可实现时时公告…
2.WebSocket实现前后端通讯-java

十五、原生JS生成随机数,如何标识请求唯一
  • Math.random()
  • Math.round()
  • Math.ceil()
  • 时间戳
    • 在每个请求后面都添加一个随机数,这样标识每个请求都是不同的,解决大部分由于缓存造成的问题
十六、树型菜单(几万条)前端如何优化?
  • 异步请求
  • 递归优化
十七、请求封装,会考虑哪些因素?
十八、大文件上传如何优化?
  • 分片上传,先判断文件的hash是否存在,已存在说明已经在服务器,实现秒传。…
十九、浏览器间的适配

之余问题

一、期望薪资

您好,可以简单介绍一下咱们的薪资构成、公司福利以及公积金的交纳比例吗?这样我可以有一种综合的判断。(随意说一个区间的话,深层理解就是最低的也能接收)

二、离开上一家的原因,对新公司的展望,期待在什么样的环境下工作
  • 想要更好的平台发展
  • 上家公司的发展让你有了瓶颈期,想要学到更多的东西和知识,但是上家公司不能够给自己提供知识,他帮助不了自己提升自我。所以想要寻找一个新的平台,去学习更多的知识。
三、想找一个什么行业或者领域的公司
四、对技术栈有什么要求
五、你最近再看什么书

《JavaScript高级程序设计》

JS是前端的核心部分。JavaScript可运行在所有主要平台的所有主流浏览器上,也可以运行在主流操作系统的服务器端。

六、有没有做过实时通讯方面的模块
七、你封装过哪些脚手架,其他同事怎么用你封装的脚手架
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Joseph365

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值