小小小幸运 发表于 2025-2-17 18:57:35

2024年最全前端面试八股文【很经典 很全面 字字珠玑】【建议收藏+关注】,2

自学几个月前端,为什么感觉什么都没学到??

这种征象在很多的初学者和自学前端的同砚中是比较的常见的。
由于自学走的弯路是比较的多的,会踩很多的坑,学习的过程中是比较的渺茫的。
最重要的是,在学习的过程中,不知道每个部分该学哪些知识点,学到什么程度才算好,学了能做什么。
很多自学的朋侪往往都是自己去找资料学习的,资料上有的大概就学到了,资料上没有的大概就没有学到。
这就会给人一个错误的信息就是,我把资料上的学完了,估计也-就差不多的了。
但是真的是如许的吗?非也,由于很多人找的资料就是很基础的。学完了也就是把握一点基础的东西。分享给你一份前端分析门路,你可以参考。
开源分享:【大厂前端面试题剖析+焦点总结学习条记+真实项目实战+最新讲解视频】
https://i-blog.csdnimg.cn/blog_migrate/cb02b4374e17507e263bbb8224aee839.png
还有很多的同砚在学习的过程中一味的追求学的速度,很快速的刷视频,写了后面忘了前面,最后什么都没有学到,什么都知道,但是什么都不懂,要具体说,也说不出个所以然。
所以学习编程肯定要注重实践操作,训练敲代码的时间肯定要多余看视频的时间。
20.动画有哪些实现方法


[*]Js
setTimeout、setInterval、requestAnimationFrame
requestAnimationFrame方法是h5提供的一种专门解决动画更新的API,欣赏器会自动以最符合的频率去刷新动画
jQuery中动画也比较实用
[*]css
animation
[*]canvas元素结合JS
[*]插件
比方 jQuery
21.浅拷贝

浅拷贝对原对象或副本的更改可能也会导致其他对象的更改。它实际上只拷贝了一层,并且只当数组和对象包的值是原始值时才会进行拷贝。

[*] 赋值运算符 =
let a=
let b=a;
console.log(b==a)//true

[*] 扩展运算符 …
let a=
let b=[...a]//把数组a的内容 挨个取出 放到b数组中
console.log(b===a) //true

[*] slice方法
let a=
let b=a.slice()
console.log(a===b) //false
a=4;
console.log(a)//4 2 3
console.log(b) //1 2 3

[*] assign方法
let a=
let b=[]
Object.assign(b,a);
a=4
console.log(a)//4 2 3
console.log(b) //1 2 3
[*] Array.from
let a=
let b=Array.from(a)
a=4
console.log(a)//4 2 3
console.log(b) //1 2 3
22.深拷贝

Javascript对象和数组如果深度嵌套,浅拷贝只能实现第一层的拷贝,但是深度的值依然和原对象共享引用。
let a=[ ,, ]
let b=[...a] //浅拷贝

a= 4
console.log(a) // [,,]
consle.log(b) // [,,] 对象b也被改变了 这时浅拷贝的弊端体现出来了

[*] 利用JSON
let a=[ ,, ]
let b=JSON.parse(JSON.stringfy(a));
a=4;
console.log(a) // [ ,, ]
console.log(b) // [ ,, ]
[*] structuredClone
let a=[ ,, ]
let b=structuredClone(a);
a=4;
console.log(a) // [ ,, ]
console.log(b) // [ ,, ]
[*] 第三方库 lodasg、rfdc
[*] 自定义函数实现
const deepCopy=(obj)=>{
if(typeof obj !==‘object’ || obj == null){
return obj;
}
const newObj= Array.isArray(obj) ? []:{};
Object.keys(obj).forEach((key)=>{
newObj=deepCopy(obj);
})
return newObj;
}
上述代码只能处理对象和数组的深度拷贝
注意理解深拷贝和浅拷贝的区别
23. 说一下原型链

原型就是一个普通对象,它是为构造函数的实例共享属性和方法;所有实例中引用
的原型都是同一个对象
利用 prototype 可以把方法挂在原型上,内存值保存一份
__proto__可以理解为指针,实例对象中的属性,指向了构造函数的原型(prototype)
24. new 操作符具体做了什么?


[*]先创建一个空对象
[*]把空对象和构造函数通过原型链进行链接
[*]把构造函数的 this 绑定到新的空对象身上
[*]根据构建函数返回的类型判断,如果是值类型,则返回对象,如果是引用类型,
就要返回这个引用类型
25.script 标签里的 async 和 defer 有什么区别?

当没有 async 和 defer 这两个属性的时间,欣赏器会立刻加载并实行指定的脚本

[*]有 async
加载和渲染后面元素的过程将和 script 的加载和实行并行进行(异步)
[*]有 defer
加载和渲染后面元素的过程将和 script 的加载并行进行(异步),但是它的实行事件要等
所有元素剖析完成之后才会实行
26. setTimeout 最小实行时间是多少?

HTML5 规定的内容:
setTimeout 最小实行时间是 4ms
setInterval 最小实行时间是 10ms
27. promise 的内部原理是什么?它的优缺点是什么?

   Promise 对象,封装了一个异步操作并且还可以获取成功或失败的结果
Promise 主要就是解决回调地狱的题目,之前如果异步使命比较多,同时他们之间
有相互依赖的关系,就只能利用回调函数处理,如许就轻易形成回调地狱,代码的可读性差,可维护性也很差
有三种状态:pending 初始状态 fulfilled 成功状态 rejected 失败状态
状态改变只会有两种环境,
pending -> fulfilled; pending -> rejected 一旦发生,状态就会凝固,不会再变
首先就是我们无法取消 promise,一旦创建它就会立刻实行,不能中途取消
如果不设置回调,promise 内部抛出的错误就无法反馈到外面
若当前处于 pending 状态时,无法得知目前在哪个阶段。
原理:
   构造一个 Promise 实例,实例需要通报函数的参数,这个函数有两个形参,分
别都是函数类型,一个是 resolve 一个是 reject
promise上还有then方法,这个方法就是来指定状态改变时简直定操作,resolve
是实行第一个函数,reject 是实行第二个函数
28.promise 和 async await 的区别是什么?


[*]都是处理异步请求的方式
[*]promise 是 ES6,async await 是 ES7 的语法
[*]async await 是基于 promise 实现的,他和 promise 都黑白壅闭性的
优缺点:
[*]promise 是返回对象我们要用 then,catch 方法去处理和捕获非常,并且书写方式
是链式,轻易造成代码重叠,不好维护,async await 是通过 tra catch 进行捕获非常
[*]async await 最大的优点就是能让代码看起来像同步一样,只要遇到 await 就会立
刻返回结果,然后再实行后面的操作
promise.then()的方式返回,会出现请求还没返回,就实行了后面的操作
29.欣赏器的存储方式有哪些?


[*]cookies
H5 标准前的本地存储方式
兼容性好,请求头自带 cookie
存储量小,资源浪费,利用贫困(封装)
[*]localstorage
H5 加入的以键值对为标准的方式
操作方便,永世存储,兼容性较好
保存值的类型被限定,欣赏器在隐私模式下不可读取,不能被爬虫
[*]sessionstorage
当前页面关闭后就会立刻清算,会话级别的存储方式
[*]indexedDB
H5 标准的存储方式,,他是以键值对进行存储,可以快速读取,适合 WEB 场

30.token 存在 sessionstorage 照旧 loaclstorage?

token:验证身份的令牌,一般就是用户通过账号密码登录后,服务端把这些凭证
通过加密等一系列操作后得到的字符串

[*]存 loaclstorage 里,后期每次请求接口都需要把它看成一个字段传给后台
[*]存 cookie 中,会自动发送,缺点就是不能跨域
[*]如果存在 localstorage 中,轻易被 XSS 攻击,但是如果做好了对应的措施,那么是
利大于弊
[*]如果存在 cookie 中会有 CSRF 攻击
31. token 的登录流程。


[*]客户端用账号密码请求登录
[*]服务端收到请求后,需要去验证账号密码
[*]验证成功之后,服务端会签发一个 token,把这个 token 发送给客户端
[*]客户端收到 token 后保存起来,可以放在 cookie 也可以是 localstorage
[*]客户端每次向服务端发送请求资源的时间,都需要携带这个 token
[*]服务端收到请求,接着去验证客户端里的 token,验证成功才会返回客户端请求
的数据
32.页面渲染的过程是怎样的?


[*]DNS 剖析
[*]创建 TCP 连接
[*]发送 HTTP 请求
[*]服务器处理请求
[*]渲染页面
5.1 欣赏器会获取 HTML 和 CSS 的资源,然后把 HTML 剖析成 DOM 树
5.2 再把 CSS 剖析成 CSSOM
5.3 把 DOM 和 CSSOM 合并为渲染树
5.4 布局
5.5 把渲染树的每个节点渲染到屏幕上(绘制)
[*]断开 TCP 连接
33.DOM 树和渲染树有什么区别?


[*]DOM 树是和 HTML 标签逐一对应的,包括 head 和隐藏元素
[*]渲染树是不包含 head 和隐藏元素
34.精灵图和 base64 的区别是什么?


[*]精灵图:把多张小图整合到一张大图上,利用定位的一些属性把小图表现在页面上,
当访问页面可以减少请求,提高加载速度
[*]base64:传输 8Bit 字节代码的编码方式,把原本二进制形式转为 64 个字符的单位,
最后构成字符串
base64 是会和 html css 一起下载到欣赏器中,减少请求,减少跨域题目,但是一些
低版本不支持,若 base64 体积比原图片大,不利于 css 的加载。
35.svg 格式了解多少?

基于 XML 语法格式的图像格式,可缩放矢量图,其他图像是基于像素的,SVG 是
属于对图像形状的描述,本质是文本文件,体积小,并且不管放大多少倍都不会失真

[*]SVG 可直接插入页面中,成为 DOM 一部分,然后用 JS 或 CSS 进行操作
<svg></svg>
[*]SVG 可作为文件被引入
<img src="pic.svg" />
[*]SVG 可以转为 base64 引入页面
36.HTTP 协议规定的协议头和请求头有什么?


[*]请求头信息:
Accept:欣赏器告诉服务器所支持的数据类型
Host:欣赏器告诉服务器我想访问服务器的哪台主机
Referer:欣赏器告诉服务器我是从那边来的(防盗链)
User-Agent:欣赏器类型、版本信息
Date:欣赏器告诉服务器我是什么时间访问的
Connection:连接方式
Cookie
X-Request-With:请求方式
[*]响应头信息:
Location:这个就是告诉欣赏器你要去找谁
Server:告诉欣赏器服务器的类型
Content-Type:告诉欣赏器返回的数据类型
Refresh:控制了的定时刷新
37.说一下什么是“同源计谋”?

http:// www. aaa.com:8080/index/vue.js
协议 子域名 主域名 端口号 资源
同源计谋是欣赏器的焦点,如果没有这个计谋就会遭受网络攻击
主要指的就是协议+域名+端口号三者一致,若其中一个不一样则不是同源,会产生
跨域
三个允许跨域加载资源的标签:img link script
跨域是可以发送请求,后端也会正常返回结果,只不外这个结果被欣赏器拦截了!

[*]JSONP
[*]CORS
[*]websocket
[*]反向代理
38.防抖和节省是什么?

都是应对页面中频繁触发事件的优化方案

[*]防抖:避免事件重复触发
利用场景:1.频繁和服务端交互 2.输入框的自动保存事件
[*]节省:把频繁触发的事件减少,每隔一段时间实行
利用场景:scroll 事件
39.有没有做过无感登录?


[*]在相应其中拦截,判断 token 返回逾期后,调用刷新 token 的接口
[*]后端返回逾期时间,前端判断 token 的逾期时间,去调用刷新 token 的接口
[*]写定时器,定时刷新 token 接口
流程:
[*]登录成功后保存 token 和 refresh_token
[*]在响应拦截器中对 401 状态码引入刷新 token 的 api 方法调用
[*]替换保存本地新的 token
[*]把错误对象里的 token 替换
[*]再次发送未完成的请求
[*]如果 refresh_token 逾期了,判断是否逾期,逾期了就清楚所有 token 重新登
40.大文件上传是怎么做的?


[*]分片上传:
1.1把需要上传的文件按照肯定的规则,分割成相同大小的数据块
1.2 初始化一个分片上传使命,返回本次分片上传的唯一标识
1.3 按照肯定的规则把各个数据块上传
1.4 发送完成后,服务端会判断数据上传的完备性,如果完备,那么就会把数据库合并成原始文件
[*]断点续传:
服务端返回,从那边开始 欣赏器自己处理
Vue篇

1. 生命周期

1.1 有哪些生命周期

体系自带:
   
[*]beforeCreate
[*]created
[*]beforeMount
[*]mounted
[*]beforeUpdate
[*]updated
[*]beforeDestroy
[*]destroyed
如果给组件加上keep-alive,会额外多
   
[*]activated
[*]deactivated
1.2初次进入页面大概组件,会实行哪些生命周期

   
[*]beforeCreate
[*]created
[*]beforeMount
[*]mounted
若组件添加keep-alive属性
   
[*]beforeCreate
[*]created
[*]beforeMount
[*]mounted
[*]acitivated
1.3在哪个阶段产生 e l , el, el,data

   
[*]$el (根节点dom) 产生阶段 : mounted
[*]$data产生阶段:created
1.4 第n(n>1)次进入组件会实行哪些生命周期

普通组件
   
[*]beforeCreate
[*]created
[*]beforeMount
[*]mounted
组件【添加keep-alive属性】
   
[*]activated
[*]若离开,则实行deactivated
2.对keep-alive的理解

   
[*]是什么
Vue自带的一个组件
功能:用来缓存组件的 【提升性能】
[*]利用场景【尽量减少发送网络请求与后端交互+反复访问的组件减少其创建次数】
缓存详情页【组件】->在详情页的activated方法中判断之前刷新的参数与当前接收的参数是否一致,如果一致就不刷新数据,否则就发送网络请求刷新数据
3.v-if 和 v-show的区别


[*]dom元素的加载区别
   v-if 是创建了一个dom节点 如果值为true时 值为false时不创建大概移除该节点
v-show 是直接创建 display:none 隐藏了

[*]利用场景不同
   
[*]初次加载v-if比v-show好 页面不会多加载dom盒子
[*]频繁切换 v-show比v-if好 创建和删除开销太大,表现和隐藏开销小
[*]如果都是值为true,初次加载v-if比v-show快,相同的节点v-show会多加一个display:none=的css属性
4.v-if 和v-for优先级

v-for 比 v-if 优先级更高 vue.js源码中可以看到 v-for 的分支在v-if之前
   
[*] 如果同一个组件 既加了v-for 也加了 v-if 那么速度会下降很多,是先实行v-for渲染列表数据,然后再每个子项都进行v-if判断,增大开销。
[*] 如果需要判断v-if建立,再实行v-for渲染子项,那么可以利用template模板
5.ref是什么

   
[*] 作用: 用来快速获取dom的,而不用document.getElement*()
[*] 利用示例:
https://blog.csdn.net/**
原生js:
document.getElementById("img")
vue:
this.$refs.imgs
6.nextTick是什么

   
[*]作用:获取更新后的dom内容
比方:
<div ref="box" @click="change">{{content}}</div>
...
data(){
        return {
                content:"old"
        }
}
methods:{
        change(){
                this.str="new";
                console.log(this.$refs.box.innerText);//输出old ref中的dom数据未来得及更新
                this.$nextTick(()=>{
                        console.log(this.$refs.box.innerText);//输出new
                })
        }
}
7.scoped 原理

   
[*]作用:让样式在本组件中收效,不影响其他组件
[*]原理:给组件节点新增自定义属性,然后css根据属性选择器添加样式,类似于下面…
<style>
        div{
                background:red;
        }
</style>
...
<div data-v-xxx>sss</div>
<div>bbb</div>
8.CSS样式穿透

   怎样让CSS只在当前组件中起作用?

[*] 给当前组件添加scoped
<style scoped></style>
如果不加,则该css样式全局收效
[*] scss
2.1 先下载 npm install sass-loader node-sass --save
2.2 需要给style 添加 属性 lang="scss"
2.3 scss样式穿透
父元素 /deep/ 子元素 {
新样式
}
比方 修改第三方插件的样式https://i-blog.csdnimg.cn/blog_migrate/c5b45b4cc6061d0147c9baae90f78dd4.png
3. stylus
3.1 下载
npm install stylus stylus-loader --svae
3.2 添加lang属性
<style lang="stylus" scoped> </style>
3.3 stylus样式穿透 [两种方式 deep 大概 >>> ]
<style scoped lang="stylus">
父元素 /deep/ 子元素 {
新样式
}
父元素 >>> 子元素 {
新样式
}

</style>
9.组件的传值


[*]父组件传值给子组件
   
[*] 父组件
<Child :data="msg"></Child>
msg和data里面的变量名一致
[*] 子组件
         {{data}}   export default{ //1. 数组 props:['data'] //2. 对象 props:{ data:String } }

[*]子组件传值到父组件
   
[*] 子组件
this.$emit("eventName",value);
[*] 父组件 在组件中利用 @事件名 绑定子组件的事件到函数

[*]兄弟组件之间的传值
   通过中转站 eventBus

[*] 创建bus.js
import Vue from ‘vue’
export default new Vue;
[*] 发送
import bus from ‘@/bus’
bus.$emit(“toBrother”,value);
[*] 接收
import bus from ‘@/bus’
mounted(){
bus.$on(“toBrother”,(data)=>{
this.data=data; //data就是其他兄弟节点通报过来的
})
}
10.computed,methods,watch有什么区别


[*]computed vs methods
   computed 盘算属性是有缓存的【只有当盘算的内容发生变革时才会重新盘算和调用】 比方 return 111 ; 调用三次 也只会调用一次computed方法,由于值不会发生变革。
methods 没有缓存 调用多少次实行多少次

[*]computed vs watch
   
[*]watch :
1.1 侦听属性 数据大概路由发生了改变才会实行
1.2 一次只能监听单个变量 变革环境 如需要监听多个比较繁琐
[*]computed
2.1 盘算的某一个属性的值改变了,盘算属性会检测到进行返回。
2.2 computed一个方法可以监听多个相关属性
11.props 和data 优先级比较

props是父组件通报进来的,data是组件本身定义的
优先级: props => methods=> data => computed=> watch
12.Vue设置代理

代理用于解决开发时的网络跨域题目,可以将所有请求交由proxy去访问
   
[*] 创建配置文件 vue.config.js
module.exports = {
publicPath:‘./’,
devServer: {
proxy: ‘http://localhost:3000’ // 打包完成后不收效
}
}
[*] 利用时url 不加前面的ip段 直接写接口 如/login
[*] 如果是开发模式 devServer不适用 会打包后出现非常
13. Vue打包路径和路由模式

打包路径配置
vue.config.js
module.exports = {
        publicPath:'./', // 默认为 / 打包后css js等文件的引入地址前缀
}
路由模式:history[默认],hash #
   前端如果自己测试项目,用hash
项目上线要求是 history模式,该怎么办?
交给后端进行重定向
14.代理和环境变量

开发环境 .env.development
VUE_APP_TITLE=
VUE_APP_ENV='dev'
VUE_APP_BASE_API="http:localhost:3000/"
生产环境 .env.production
VUE_APP_TITLE=
VUE_APP_ENV='pro'
VUE_APP_BASE_API="http:127.0.0.1:3000/"
在axios封装的时间其base_url
        let base_url=""
        if(process.env.VUE_APP_ENV=='pro'){
                base_url=process.baseApi+url;
        }else{
                // dev模式可以通过代理去访问 直接为默认的url即可
                base_url=url;
        }
15.Vue路由

路由模式:history[默认],hash #
区别:
   
[*]表现形式不同
hash模式多了#
[*]跳转
访问 http:localhost:8888/id
history:会发送请求
hash: 不会发送
[*]打包后 前端自测要利用hash,如果利用history会出现空白
16.SPA及SPA的缺点

SPA是什么?单页面应用
缺点:
   
[*]SEO优化不好
[*]性能不是特殊好【需要首页优化】
17.怎样理解 MVVM 的?

是 Model-View-ViewModel 的缩写。前端开发的架构模式
M:模子,对应的就是 data 的数据
V:视图,用户界面,DOM
VM:视图模子:Vue 的实例对象,连接 View 和 Model 的桥梁
焦点是提供对 View 和 ViewModel 的双向数据绑定,当数据改变的时间,ViewModel
能监听到数据的变革,自动更新视图,当用户操作视图的时间,ViewModel 也可以监听到视
图的变革,然后关照数据进行改动,这就实现了双向数据绑定
ViewModel 通过双向绑定把 View 和 Model 连接起来,他们之间的同步是自动的,
不需要以为干涉,所以我们只需要关注业务逻辑即可,不需要操作 DOM,同时也不需要关
注数据的状态题目,由于她是由 MVVM 同一管理
18.v-for 中的 key 值的作用是什么?

key 属性是 DOM 元素的唯一标识
作用:

[*]提高假造 DOM 的更新
[*]若不设置 key,可能会触发一些 bug
[*]为了触发过度效果
19.VUE路径传值

显式传值
        ==>localhost:8080/about?a=1;
        this.$router.push({
                path:'/about',
                query:{
                        a:1       
                }
        })
        this.$router.push({
                path:'/about?a=1'
        })
        使用query接收值
        this.$router.query.a
隐式传值
        this.$router.push({
                name:'/About',
                params:{a:1}
        })
        接收:
        this.$router.params.a
20.vue 中遍历全局的方法有哪些?


[*] 普通遍历,对象.forEach()
arr.forEach(function(item,index,arr){
console.log(item,index)
})
[*] 对元素同一操作 对象.map()
var newarr = arr.map(function(item){
return item+1
})
3.查找符合条件的元素 对象.filter()
arr.filter(function(item){
        if(item > 2){
                return false
        }else{
                return true
        }
})
4.查询符合条件的元素,返回索引 对象.findindex()
arr.finindex(function(item){
        if(item>1){
                return true
        }else{
                return false
        }
})

[*]对象.evening() 遇到不符合的对象会制止
[*]对象.some() 找到符合条件的元素就制止
21. vue 的过滤器怎么利用?

vue 的特性,用来对文本进行格式化处理
利用它的两个地方,一个是插值表达式,一个是 v-bind
分类:

[*] 全局过滤器
Vue.filter(‘add’,function(v){
return v < 10 ? ‘0’ + v : v
})
       {{33 | add}}
[*] 本地过滤器
和 methods 同级
filter:{
add:function(v){
return v < 10 ? ‘0’ + v : v
}
}
22.怎样封装一个组件?


[*]利用 Vue.extend()创建一个组件
[*]利用 Vue.components()方法注册组件
[*]如果子组件需要数据,可以在 props 中接收定义
[*]子组件修改好数据,要把数据通报给父组件,可以用 emit()方法
原则:
(1) 把功能拆开
(2)尽量让组件原子化,一个组件做一件事变
(3)容器组件管数据,展示组件管视图
23.封装一个可复用的组件,需要满意什么条件?


[*]低耦合,组件之间的依赖越小越好
[*]最好从父级传入信息,不要在公共组件中请求数据
[*]传入的数据要进行校验
[*]处理事件的方法写在父组件中
24.路由导航守卫有哪些

全局、路由独享、组件内
   
[*]全局【参数 to from next】
beforeEach、beforeResolve, afterEach
[*]路由独享
beforeEnter
[*]组件内【很少】
beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave
const router = new VueRouter({
        mode:"history",
        base:process.env.BASE_URL,
        routes
})
router.beforeEach((to, from,next)=>{
        console.log(to,from,next)//to是到哪个页面 from从哪来 next 就是保安
        if(有权限){
                next() // 放行
        }else{
                router.push('/login') //转发到其他页面
        }
})
在进入某个页面之前进行拦截,可以进行权限判断
分享

开源分享:【大厂前端面试题剖析+焦点总结学习条记+真实项目实战+最新讲解视频】
https://i-blog.csdnimg.cn/blog_migrate/da15cad739535fff1f77a5a42f7413b7.png
https://i-blog.csdnimg.cn/blog_migrate/2d1c65f48e949a5f9c3c515340bab89f.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 2024年最全前端面试八股文【很经典 很全面 字字珠玑】【建议收藏+关注】,2