前端八股文面试全套真题【含答案】- JavaScript篇
1.不会冒泡的事件有哪些?
在 JavaScript 和浏览器中,绝大多数事件都会按照 DOM 事件流模型冒泡,即事件会从目标元素开始向上冒泡到它的父元素,并最终到达 document 元素。然而,也有一些事件是不会冒泡的。这些事件通常直接在目标元素上触发,并不会向上传播。
以下是一些不会冒泡的事件的示例:
- focus :当元素获得焦点时触发,例如通过键盘或鼠标点击。这是一个不会冒泡的事件。
- blur :当元素失去焦点时触发。这也是一个不会冒泡的事件,
- focusin:与 focus 类似,但会在元素或其父元素上触发(冒泡),因此这个事件是特例。
- focusout:与blur类似,但会在元素或其父元素上触发(冒泡),因此这个事件是特例。
- load :当图像、音频、视频或其他资源加载完成时触发。例如,在 img 元素上触发的 1oad 事件不会冒泡。
- unload :当页面即将被导航离开时触发。这通常用于执行清理工作,也不会冒泡。
- stop :通常与 media 元素相关,例如 audio 或 video 元素。这是在媒体播放停止时触发的事件。
- readystatechange:当 document 的 readystate 改变时触发。这通常石在页面加载时使用。
- scroll:当元素滚动时触发。这个事件在某些浏览器中可能会冒泡。
这些事件通常直接在目标元素上触发,并且不会传播到父元素上。
2.mouseEnter和mouseOver 有什么区别?
mouseenter 和mouseover 是两个用于处理鼠标进入元素时的事件,但它们在一些关键点上有所不同:
1.事件冒泡:
- mouseenter:这个事件在鼠标指针首次进入特定元素(或其子元素)时触发。当鼠标进入元素时,会触发该元素的 mouseenter事件,但不会在元素的子元素上冒泡。因此,该事件通常用于检测鼠标首次进入元素时的动作。
- mouseover:这个事件在鼠标指针移动到某个元素上时触发,不论它是直接在这个元素上触发还是在其子元素上触发。当鼠标进入一个元素时,它会在该元素上触发 mouseover 事件,然后冒泡到父元素
2.事件触发范围:
- mouseenter:当鼠标进入元素自身时触发,只在目标元素上触发,不会因为鼠标移动到其子元素上而再次触发,
- mouseover:不仅在目标元素上触发,也在其子元素上触发。所以,如果鼠标从一个子元素移动到另一个子元素,这些元素的父元素会触发多个mouseover 事件。
3.事件对象的属性:
- mouseenter :事件对象通常会有 relatedTarget 属性,它指向鼠标移动前的那个元素。如果 relatedTarget 指向目标元素或为 nu11,那么事件就不会触发。
- mouseover:事件对象也会有relatedTarget 属性,通常指向从中离开的那个元素。
使用场景
- mouseenter 更适合用来检测鼠标首次进入某个元素时的行为,
- mouseover更适合用来检测鼠标在元素或其子元素之间移动时的行为,因为它冒泡。
在实际使用时,如果你只想在鼠标首次进入元素时触发某些行为(比如显示一个提示),可以使用 mouseenter;如果你希望在鼠标移动到某个元素或其子元素上时都触发某些行为(比如动态改变样式),可以使用mouseover。
3.Messagechannel是什么,有什么使用场景?
Messagechannel 是一个 JavaScript API,用于在两个独立的执行环境(如 WebWorkers 或者不同的 browsing contexts)之间建立双向通信的通道。
Messagechannel 提供了两个通信端点(port1和 port2),可以在两个不同的执行环境之间传递消息,并通过事件监听的方式来处理这些消息。
使用场景包括但不限于:
- Web Workers 通信:在 Web 开发中, Messagechannel 通常用于在主线程和 Web Worker 之间建立通信通道,以便主线程与 Worker 之间传递消息和数据。
- 不同浏览上下文(browsing context)之间的通信:在现代浏览器中,多个标2 签页、iframe 或者其他类型的 browsing context 可以通过Messagechannel实现通信。
- SharedWorker 通信:Messagechannel 可以用于在主线程和 SharedWorker 之间建立通信通道。
- 服务端和客户端之间的通信: Messagechanne1l 可以用于客户端(如浏览4.器)与服务端(如 WebSocket 服务器)之间的通信,特别是在与 WebSocket或其他类似技术结合使用时。
- 异步任务处理:在某些场景中,使用 Messagechannel可以更方便地处理异步任务,因为它提供了独立于主线程的通信通道。
使用示例
下面是一个简单的示例,展示如何使用 Messagechannel 在主线程和 WebWorker 之间建立通信通道:

在上面的示例中,我们创建了一个 Messagechannel,并通过 port1 和port2 进行通信。我们将port2 发送给 Web Worker, port1 留在主线程。然后,主线程可以通过监听 port1的 onmessage 事件来接收来自WebWorker 的消息,并通过 port1.postMessage()向 Web Worker 发送消息。
4.async、await 实现原理
JavaScript 异步编程回顾
由于 JavaScript 是单线程执行模型,因此必须支持异步编程才能提高运行效率。异步编程的语法目标是让异步过程写起来像同步过程。
1.回调函数
回调函数,就是把任务的第二段单独写在一个函数里面等到重新执行这个任务的时候,就直接调用这个函数。

回调函数最大的问题是容易形成回调地狱,即多个回调函数嵌套,降低代码可读性,增加逻辑的复杂性,容易出错。

2.Promise
为解决回调函数的不足,社区创造出 Promise。

简单的 Promise 实现,窥探下本质
Promise 实际上是利用编程技巧将回调函数的横向加载,改成纵向加载,达到链式调用的效果,避免回调地狱。最大问题是代码冗余,原来的任务被 Promise 包装了一下,不管什么操作,一眼看去都是一堆 then,原来的语义变得很不清楚。
3.async、await
为了解决 Promise 的问题,async、await 在 ES8 中被提了出来,是目前为止最好的解决方案

async、await 函数写起来跟同步函数一样,条件是需要接收 Promise 或原始类型的值。异步编程的最终目标是转换成人类最容易理解的形式。
async、await
分析 async、await 实现原理之前,先介绍下预备知识
1. generator
generator 函数是协程在 ES6 的实现。协程简单来说就是多个线程互相协作,完成异步任务。
整个 generator 函数就是一个封装的异步任务,异步操作需要暂停的地方,都用yield 语句注明。generator 函数的执行方法如下!

- gen()不会立即执行,而是一上来就暂停,返回一个 Iterator 对象(具体可以参考 Iterator遍历器 )
- 每次 g.next()都会打破暂停状态去执行,直到遇到下一个 yield 或者return
- 遇到 yield 时,会执行 yield 后面的表达式,并返回执行之后的值,然后再次进入暂停状态,此时 done:false。
- next 函数可以接受参数,作为上个阶段异步任务的返回结果,被函数体内的变量接收
- 遇到 return 时,会返回值,执行结束,即done:true
- 每次 g.next()的返回值永远都是 {value:...,done:...}的形式
2.thunk函数
JavaScrint 中的 thunk 函数(译为转换程序)简单来说就是把带有回调函数的多参数函数转换成只接收回调函数的单参数版本

单纯的 thunk 函数并没有很大的用处,大牛们想到了和 generator 结合:

thunk 函数的真正作用是统一多参数函数的调用方式,在 next 调用时把控制权交还给 generator,使 generator 函数可以使用递归方式自启动流程

有了自启动的加持之后,generator 函数内就可以写"同步"的代码了。generator 函数也可以与 Promise 结合:

generator 可以暂停执行,很容易让它和异步操作产生联系,因为我们在处理异步操作时,在等待的时候可以暂停当前任务,把程序控制权交还给其他程序,当异步任务有返回时,在回调中再把控制权交还给之前的任务。generator 实际上并没有改变 JavaScript 单线程、使用回调处理异步任务的本质。
http://3.co 函数库
每次执行 generator 函数时自己写启动器比较麻烦。co函数库 是一个 generator函数的自启动执行器,使用条件是 generator 函数的 yield 命令后面,只能是thunk 函数或 Promise 对象,c0 函数执行完返回一个 Promise 对象,

co 函数库的源码实现其实就是把上面两种情况做了综合:

4.理解 async、await
一句话,async、await 是 co 库的官方实现。也可以看作自带启动器的 generator函数的语法糖。不同的是,async、await 只支持 Promise 和原始类型的值,不支持 thunk 函数。

总结
不论以上哪种方式,都没有改变 avaScript 单线程、使用回调处理异步任务的本质。人类总是追求最简单易于理解的编程方式。
5.Proxy 能够监听到对象中的对象的引用吗?
Proxy 可以监听到对象中的对象的引用
当使用 Proxy 包装一个对象时,可以为该对象的任何属性创建一个拦截器,包括属性值为对象的情况。
下面展示了如何使用 Proxy 来监听对象中对象引用的变化:

我们通过 Proxy 创建了一个代理对象 proxyobj ,它包装了原始的 obj。然后我们对 proxyobj 中的nestedobj.foo 进行赋值操作,这会触发 set 拦截器并打印相应的信息。
通过使用适当的拦截器函数,可以实现对对象中对象引用的监听和修改。这使得我们可以在需要时执行自定义的操作,例如记录更改、验证或触发其他事件等
JavaScript面试真题323问

- 第1题:不会冒泡的事件有哪些?
- 第2题:mouseEnter 和 mouseOver 有什么区别?
- 第3题:MessageChannel 是什么,有什么使用场景?
- 第4题:async、await 实现原理
- 第5题:Proxy 能够监听到对象中的对象的引用吗?
- 第6题:如何让 var 「a, b]={a:1,b:2}解构赋值成功?
- 第7题:下面代码会输出什么?
- 第8题:描述下列代码的执行结果
- 第9题:什么是作用域链?
- 第10题:bind、call、apply 有什么区别?如何实现一个bind?
- 第11题:common.js和es6中模块引入的区别?
- 第12题:说说 vue3 中的响应式设计原理
- 第13题:script标签放在header里和放在body底部里有什么区别?
- 第14题:下面代码中,点击“+3”按钮后,age 的值是什么?
- 第15题:Vue中,created和mounted两个钩子之间调用时间差值受什么影响?
- 第16题:vue中,推荐在哪个生命周期发起请求?
- 第17题:不会冒泡的事件有哪些?
- 第18题:mouseEnter 和 mouseOver 有什么区别?
- 第19题:为什么Node在使用es module时必须加上文件扩展名?
- 第20题:package.json 文件中的 devDependencies 和 dependencies 对象有什么区别?
- 第21题:React Portals 有什么用?
- 第22题:react 和 react-dom 是什么关系?
- 第23题:MessageChannel 是什么,有什么使用场景?
- 第24题:React 中为什么不直接使用 requestIdleCallback?
- 第25题:为什么 react 需要 fiber 架构,而 Vue 却不需要?
- 第26题:子组件是一个 Portal,发生点击事件能冒泡到父组件吗?
- 第27题:async、await 实现原理
- 第28题:前端性能优化指标有哪些?怎么进行性能检测?
- 第29题:Proxy 能够监听到对象中的对象的引用吗?
- 第30题:css 中的 animation、transition、 transform 有什么区别
- 第31题:使用Promise实现红绿灯交替重复亮
- 第32题:如何让 var 「a, bl= fa: 1,b: 2} 解构赋值成功?
- 第33题:说说React render方法的原理?在什么时候会被触发?
- 第34题:下面代码会输出什么?
- 第35题:什么是 DOM 和 BOM?
- 第36题:简单描述从输入网址到页面显示的过程
- 第37题:SPA(单页应用)首屏加载速度慢怎么解决?
- 第38题:RESTfu 接口规范是什么?
- 第39题:利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3
- 第40题:说说new操作符具体干了什么?
- 第41题:webpack5的主要升级点有哪些?
- 第42题:ty...catch 可以捕获到异步代码中的错误吗?
- 第43题:说说你对低代码的了解
- 第44题:说说WebSocket和HTTP的区别
- 第45题:说下Vite的原理
- 第46题:e.target 和 e.currentTarget 有什么区别?
- 第47题:说说你对计算机网络模型的理解
- 第48题:Map 和 Set 的用法以及区别
- 第49题:最大子序和
- 第50题:说说 https 的握手过程
- 第51题:HTTP2中,多路复用的原理是什么?
- 第52题:说说你对"三次握手"、"四次挥手”的理解
- 第53题:如何确保你的构造函数只能被new调用,而不能被普通调用
- 第54题:为什么推荐将静态资源放到cdn上?
- 第55题:说说React事件和原生事件的执行顺序
- 第56题:Vue2.0为什么不能检査数组的变化,该怎么解决?
- 第57题:说说Vue 页面渲染流程
- 第58题:ES5怎么实现继承
- 第59题:请简述 ==的机制
- 第60题:怎么做移动端的样式适配?
- 第61题:arquments 这种类数组,如何遍历类数组?
- 第62题:遍历数组的方式有哪些?
- 第63题:setTimeout 延时写成0,一般可以什么场景下使用?
- 第64题:怎么预防用户快速连续点击,造成数据多次提交?
- 第65题:说说下面代码的输出结果
- 第66题:怎么实现大型文件上传?
注:文中的 前端JavaScript面试题汇总PDF已经打包完毕,希望对大家有帮助!加油
更多推荐

所有评论(0)