旺财大狼狗 發表於 2025-5-15 11:45:00

2025年每个前端开发人员都应该准备的 40 个 JavaScript 面试问题

<p>无论你是在为下一个重要的前端职位做准备,还是只是想温习一下 JS 基础知识,这<strong>40 个 JavaScript 面试题</strong>都能帮助你脱颖而出,<strong>自信</strong>满满💪🏻。从基础知识到高级技巧,应有尽有。<br>
快来深入了解吧!🔥</p>
<h2 id="40-个-javascript-面试题及答案">40 个 JavaScript 面试题及答案</h2>
<h3 id="1什么是-javascript">1.❓什么是 JavaScript?</h3>
<p>了解 JavaScript 的核心是什么,能帮你为其他一切打下坚实的基础,无论是 DOM 操作、异步编程,还是像 React 或 Vue 这样的框架。这通常是任何前端面试的首要问题之一。</p>
<p><strong>答:</strong><br>
JavaScript 是一种<strong>高级、解释型、动态编程语言,</strong>主要用于在网站上创建交互式动态内容。它在浏览器(客户端)中运行,但也可以使用<strong>Node.js</strong>等环境在服务器上运行。JavaScript 支持<strong>面向对象</strong>、<strong>函数式</strong>和<strong>事件驱动的</strong>编程范式,使其成为前端和后端开发的强大工具。</p>
<hr>
<h3 id="var2--let-和-之间有什么区别const"><code>var</code>2. 🔁 、<code>let</code>、 和 之间有什么区别<code>const</code>?</h3>
<p>选择正确的关键字来声明变量可以避免与作用域、提升和不变性相关的错误。面试官问这个问题是为了评估你对现代 ES6+ JavaScript 的理解程度。</p>
<p><strong>回答:</strong></p>
<ul>
<li><code>var</code>➡<strong>函数具有作用域</strong>,可提升,且可在同一作用域内重复声明。ES6 之前常用。</li>
<li><code>let</code>➡<strong>块作用域</strong>,在同一作用域内不可重新声明,并且被提升但未初始化(TDZ - 暂时死区)。</li>
<li><code>const</code>➡<strong>块作用域</strong>,不能重新分配(不可变绑定),但用声明的对象和数组<code>const</code>仍然可以变异。</li>
</ul>
<p>使用<code>let</code>和<code>const</code>可以获得更干净、更可预测的代码。<code>const</code>除非值需要改变,否则通常是首选。</p>
<hr>
<h3 id="3️-javascript-中的数据类型有哪些">3.🏷️ JavaScript 中的数据类型有哪些?</h3>
<p>了解数据在 JavaScript 中的表示和行为方式有助于防止与类型相关的错误并提高调试技能。</p>
<p><strong>答:</strong><br>
JavaScript 有两大类数据类型:</p>
<ul>
<li>
<p><strong>原始类型</strong>(不可变,按值存储):<br>
<code>string</code>,,,,,,,<code>number``boolean``null``undefined``symbol``bigint</code></p>
</li>
<li>
<p><strong>非原始类型</strong>(可变,通过引用存储):<br>
<code>object</code>,,<code>array``function</code></p>
</li>
</ul>
<p>在进行赋值、比较和内存管理时,理解原始类型和非原始类型之间的区别至关重要。</p>
<hr>
<h3 id="4-和-有什么区别"><code>==</code>4. 🧮和 有什么区别<code>===</code>?</h3>
<p>这个问题测试您对 JavaScript 类型强制系统的掌握程度,如果误解,通常会导致细微的错误。</p>
<p><strong>回答:</strong></p>
<ul>
<li><code>==</code>➡ 在比较之前进行<strong>类型强制转换</strong>(松散相等)。例如:<code>'5' == 5</code>→<code>true</code></li>
<li><code>===</code>➡ 比较<strong>值和类型</strong>(严格相等)。例如:<code>'5' === 5</code>→<code>false</code></li>
</ul>
<p>始终使用<code>===</code>此选项可避免由于类型强制转换而导致的意外行为。它可确保比较结果更清晰、更可预测。</p>
<hr>
<h3 id="5--javascript-中的提升是什么">5. 📦 JavaScript 中的提升是什么?</h3>
<p>提升是一个基本概念,它影响变量和函数在不同作用域中的访问方式。面试官会用它来测试你对执行上下文的理解。</p>
<p><strong>答:</strong><br>
提升是 JavaScript 的默认行为,即在代码执行之前<strong>将变量和函数声明移动到其范围的顶部。</strong></p>
<ul>
<li>用 声明的变量<code>var</code>将被提升并用 初始化<code>undefined</code>。</li>
<li><code>let</code>和<code>const</code>也被提升,但它们在<strong>临时死区(TDZ)</strong>中仍未初始化。</li>
<li>函数声明被完全提升,这意味着您可以在代码中实际定义之前调用它们。</li>
</ul>
<h3 id="6--javascript-中的闭包是什么">6. 🔐 JavaScript 中的闭包是什么?</h3>
<p>闭包是 JavaScript 中的一个核心概念,在回调、柯里化、数据隐私和函数式编程模式中被广泛使用。</p>
<p><strong>回答:</strong></p>
<p>当函数“记住”其外部词法范围中的变量(即使在外部函数执行完毕之后)时,就会创建闭包。</p>
<p>例子:</p>
<pre><code>function outer() {
let counter = 0;
return function inner() {
    counter++;
    return counter;
};
}
const count = outer();
count(); // 1
count(); // 2

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<p>在这里,即使已经运行,<code>inner</code>仍然可以访问。<code>counter``outer</code></p>
<hr>
<h3 id="7️同步代码和异步代码有什么区别">7.⏲️同步代码和异步代码有什么区别?</h3>
<p>JavaScript 是单线程的。理解异步行为对于构建高性能的 Web 应用至关重要。</p>
<p><strong>回答:</strong></p>
<ul>
<li><strong>同步代码</strong>会阻止进一步执行,直到完成为止,它会逐行运行。</li>
<li><strong>异步代码</strong>在后台运行(例如 HTTP 请求、计时器),允许程序继续执行其他任务。它使用回调、Promises 或<code>async/await</code>来处理执行流程。</li>
</ul>
<hr>
<h3 id="8什么是箭头函数">8.➡什么是箭头函数?</h3>
<p>箭头函数简洁,并且在方面表现不同<code>this</code>。非常适合函数式编程。</p>
<p><strong>答:</strong><br>
箭头函数提供了一种简写语法 ( <code>() =&gt; {}</code>),并且不绑定自身的<code>this</code>、<code>arguments</code>、<code>super</code>或<code>new.target</code>。这使得它们非常适合用作短函数和回调,但不适合用作方法或构造函数。</p>
<hr>
<h3 id="9️什么是词法范围">9.🗂️什么是词法范围?</h3>
<p>理解词法范围有助于您推断变量可见性以及闭包的工作原理。</p>
<p><strong>答:</strong> <strong>词法作用域</strong>是指变量的作用域由其在源代码中的位置决定。内部函数可以访问在外部作用域中声明的变量。这也是闭包即使在其父函数返回后仍可以访问变量的原因。</p>
<hr>
<h3 id="10什么是事件循环">10.🌀什么是事件循环?</h3>
<p>它是 JS 异步行为的核心。了解这一点将有助于你避免竞争条件并提高性能。</p>
<p><strong>答:</strong><br>
事件<strong>循环</strong>管理程序多个代码块随时间推移的执行。它在<strong>调用堆栈</strong>和<strong>回调/任务队列</strong>之间移动任务。通过在调用堆栈为空时运行任务来确保非阻塞行为。</p>
<h3 id="11--如何克隆一个对象">11. 🧰 如何克隆一个对象?</h3>
<p>复制对象很常见,但您需要知道何时复制浅层,何时复制深层,以避免引用错误。</p>
<p><strong>回答:</strong></p>
<ul>
<li><strong>浅拷贝</strong>:<code>Object.assign({}, obj)</code>或<code>{...obj}</code></li>
<li><strong>深度复制</strong>:(<code>JSON.parse(JSON.stringify(obj))</code>注意:丢失函数、日期和特殊类型)</li>
<li>高级:使用 Lodash 之类的库<code>cloneDeep()</code>来深度克隆复杂对象。</li>
</ul>
<hr>
<h3 id="map12--filter-和-之间有什么区别reduce"><code>map()</code>12. 🧾 、<code>filter()</code>、 和 之间有什么区别<code>reduce()</code>?</h3>
<p>这些是处理数组和数据转换的基本工具。</p>
<p><strong>回答:</strong></p>
<ul>
<li><code>map()</code>:转换每个项目并返回一个新数组。</li>
<li><code>filter()</code>:根据条件过滤项目。</li>
<li><code>reduce()</code>:将值累积为单个结果(例如,总和、对象合并)。</li>
</ul>
<hr>
<h3 id="13-️-如何检查一个值是否为数组">13. 🕵🏻‍♂️ 如何检查一个值是否为数组?</h3>
<p>数组和对象都是类型<code>"object"</code>,因此需要一种可靠的方法。</p>
<p><strong>答案:</strong><br>
用于<code>Array.isArray(value)</code>精确检查。避免使用<code>typeof</code>,因为它返回<code>"object"</code>数组。</p>
<hr>
<h3 id="14--javascript-中的解构是什么">14. 💣 JavaScript 中的解构是什么?</h3>
<p>解构使你的代码更清晰、更易读。</p>
<p><strong>回答:</strong></p>
<p>通过解构,您可以将数组中的值或对象的属性解包到不同的变量中。</p>
<pre><code>const = ;
const { name } = { name: "Alice" };

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<p>这简化了嵌套结构和 API 的数据访问。</p>
<hr>
<h3 id="15--什么是扩展运算符">15. 🔗 什么是扩展运算符?</h3>
<p>Spread 用于一切事物,克隆、合并、函数调用等。</p>
<p><strong>回答:</strong></p>
<p>扩展运算符 ( <code>...</code>) 允许你扩展可迭代对象的元素(如数组或对象):</p>
<pre><code>const arr = ;
const newArr = [...arr, 3]; //

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<p>它对于 React 中的不变性模式和合并数据很有用。</p>
<h3 id="16-javascript-中的承诺是什么">16.🧵 JavaScript 中的承诺是什么?</h3>
<p>与回调相比,承诺对于以更清晰、更易读的方式管理异步操作至关重要。</p>
<p><strong>回答:</strong></p>
<p>Promise 代表异步操作的结果,具有三种状态:<code>pending</code>、<code>fulfilled</code>和<code>rejected</code>。</p>
<p>与深度嵌套的回调(回调地狱)不同,Promise 使用<code>.then()</code>和<code>.catch()</code>进行链接:</p>
<pre><code>fetch('api/data')
.then(res =&gt; res.json())
.then(data =&gt; console.log(data))
.catch(err =&gt; console.error(err));

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<hr>
<h3 id="17-什么是-asyncawait">17.💤 什么是 async/await?</h3>
<p><code>async/await</code>简化了承诺的工作,使异步代码看起来和行为更像同步代码。</p>
<p><strong>答案:</strong> <code>async</code>函数返回一个承诺,并<code>await</code>暂停执行直到该承诺解决或拒绝。</p>
<p>这使得代码更清晰、更容易理解:</p>
<pre><code>async function getData() {
try {
    const res = await fetch('api/data');
    const data = await res.json();
    console.log(data);
} catch (error) {
    console.error(error);
}
}

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<hr>
<h3 id="18--有什么用fetch">18. 📡 有什么用<code>fetch()</code>?</h3>
<p><code>fetch()</code>是发出网络请求的现代标准。</p>
<p><strong>答:</strong> <code>fetch()</code>是一个用于发出 HTTP 请求并返回 Promise 的浏览器 API。它可用于 GET、POST、PUT、DELETE 请求,并且可以与 结合使用<code>async/await</code>。</p>
<hr>
<h3 id="19如何使用-asyncawait-处理错误">19.🚨如何使用 async/await 处理错误?</h3>
<p>异步代码更容易出错。优雅的错误处理至关重要。</p>
<p><strong>回答:</strong></p>
<p>在调用周围使用<code>try...catch</code>块<code>await</code>:</p>
<pre><code>try {
const res = await fetch(url);
const data = await res.json();
} catch (err) {
console.error("Failed to fetch:", err);
}

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<p>这避免了未处理的承诺拒绝。</p>
<hr>
<h3 id="20--什么是promiseall">20. 🧪 什么是<code>Promise.all()</code>?</h3>
<p>它是多个 API 调用等并行异步操作的关键技术。</p>
<p><strong>答案:</strong> <code>Promise.all()</code>接受一个 Promise 数组,所有 Promise 都成功时解析,任何失败时拒绝。适用于并行加载:</p>
<pre><code>await Promise.all();

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<h3 id="21什么是-javascript-模块">21.🧱什么是 JavaScript 模块?</h3>
<p>模块允许您跨文件组织和重用代码。</p>
<p><strong>答:</strong><br>
JS 模块用于<code>export</code>共享和<code>import</code>使用代码。它们支持封装,并广泛应用于现代开发(ES6+、React、Node.js 等)。</p>
<hr>
<h3 id="null22-️和-有什么区别undefined"><code>null</code>22. 🕳️和 有什么区别<code>undefined</code>?</h3>
<p>这些是错误和混乱的常见根源。</p>
<p><strong>回答:</strong></p>
<ul>
<li><code>undefined</code>:已声明但尚未赋值的变量。</li>
<li><code>null</code>:明确指定“无值”。</li>
</ul>
<p>有意使用<code>null</code>;避免留下价值<code>undefined</code>。</p>
<hr>
<h3 id="23--解释一下-debounce-和-throttle">23. 📈 解释一下 debounce 和 throttle。</h3>
<p>这些技术优化了性能,特别是在事件密集型 UI 中。</p>
<p><strong>回答:</strong></p>
<ul>
<li><strong>去抖动</strong>:等待 X 毫秒内未调用某个函数后再运行该函数(例如,搜索输入)。</li>
<li><strong>节流</strong>:确保某个功能每 X 毫秒最多运行一次(例如,滚动事件)。</li>
</ul>
<hr>
<h3 id="24this关键词是什么">24.🧷<code>this</code>关键词是什么?</h3>
<p>误解<code>this</code>导致面向对象 JS 中出现很多 bug。</p>
<p><strong>答:</strong> <code>this</code>指向拥有当前代码的对象。在方法中,它指向父对象。在常规函数中,<code>this</code>取决于调用上下文(或处于<code>undefined</code>严格模式)。箭头函数<strong>没有</strong>自己的<code>this</code>。</p>
<hr>
<h3 id="25什么是原型继承">25.🌳什么是原型继承?</h3>
<p>这是 JavaScript 实现 OOP 的方式,不是使用类(直到 ES6),而是使用原型。</p>
<p><strong>答:</strong><br>
原型继承是指对象通过原型链从其他对象继承属性。它是一种灵活且动态的传统继承替代方案。</p>
<h3 id="26什么是-dom">26.🧩什么是 DOM?</h3>
<p>前端开发人员不断操作 DOM 来更新 UI。</p>
<p><strong>答:</strong><br>
文档对象 模型<strong>(DOM)</strong>是表示网页 HTML 元素的树状结构。JavaScript 可以动态访问和操作此结构。</p>
<hr>
<h3 id="27-️️-dom-比较-中和有-什么区别">27. 🕵️‍♂️ DOM 比较 中<code>==</code>和有 什么区别?<code>===</code></h3>
<p>如果类型不匹配,比较 DOM 元素可能会产生意外的结果。</p>
<p><strong>答:</strong><br>
同样的规则适用:用于<code>===</code>严格相等。比较 DOM 节点时,<code>node1 === node2</code>检查两者是否指向<strong>同一个元素</strong>。</p>
<hr>
<h3 id="28--如何选择-dom-中的元素">28. 📚 如何选择 DOM 中的元素?</h3>
<p>选择元素是任何 DOM 操作的第一步。</p>
<p><strong>回答:</strong></p>
<ul>
<li><code>document.getElementById('id')</code></li>
<li><code>document.querySelector('.class')</code></li>
<li><code>document.querySelectorAll('div')</code></li>
</ul>
<p>这些方法可帮助您动态地定位和修改元素。</p>
<hr>
<h3 id="29️什么是事件委托">29.🖱️什么是事件委托?</h3>
<p>它通过附加更少的事件监听器来提高性能。</p>
<p><strong>答:</strong><br>
事件委托使用<strong>冒泡</strong>来捕获 DOM 树上层的事件。例如,将一个点击监听器附加到父级,而不是将多个监听器附加到每个子级。</p>
<hr>
<h3 id="30--如何防止事件中的默认行为">30. 🧼 如何防止事件中的默认行为?</h3>
<p>对于表单处理或自定义交互来说,防止默认行为通常是必要的。</p>
<p><strong>答案:</strong>在事件处理程序内部<br>
调用以停止默认浏览器行为(如表单提交或链接导航)。<code>event.preventDefault()</code></p>
<h3 id="31--什么是模板文字">31. 📜 什么是模板文字?</h3>
<p>它们使字符串格式更加清晰、更加动态。</p>
<p><strong>回答:</strong></p>
<p>模板文字使用反引号并支持插值:</p>
<pre><code>const name = "Bob";
console.log(`Hello, ${name}!`);

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<p>它们还支持多行字符串。</p>
<hr>
<h3 id="32什么是回调函数">32.📞什么是回调函数?</h3>
<p>回调是异步 JS、事件处理和数组方法的基础。</p>
<p><strong>答:****回调函数</strong><br>
作为参数传递给另一个函数,并在稍后执行。它支持事件处理程序和异步逻辑等功能。</p>
<hr>
<h3 id="33javascript-中的假值是什么">33.❌JavaScript 中的假值是什么?</h3>
<p>条件逻辑通常取决于真/假检查。</p>
<p><strong>答:</strong><br>
假值包括:<code>false</code>、<code>0</code>、<code>''</code>(空字符串)、<code>null</code>、<code>undefined</code>、<code>NaN</code>。其他所有值均为真值。这些会影响条件和短路逻辑。</p>
<hr>
<h3 id="typeof34-和-之间的区别instanceof"><code>typeof</code>34. ⚖和 之间的区别<code>instanceof</code>?</h3>
<p>类型检查有助于调试和执行逻辑。</p>
<p><strong>回答:</strong></p>
<ul>
<li><code>typeof</code>:返回描述类型的字符串(<code>'object'</code>、、等)<code>'function'</code>。<code>'string'</code></li>
<li><code>instanceof</code>:检查对象是否从构造函数的原型继承。</li>
</ul>
<hr>
<h3 id="35-什么是立即调用函数表达式iife">35.🔥 什么是立即调用函数表达式(IIFE)?</h3>
<p>有助于避免污染全局范围和创建孤立的代码块。</p>
<p><strong>回答:</strong></p>
<p>IIFE在定义后立即运行<strong>:</strong></p>
<pre><code>(function() {
console.log("Runs immediately!");
})();

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<p>非常适合模块和闭包。</p>
<h3 id="36️浅拷贝和深拷贝有什么区别">36.🗃️浅拷贝和深拷贝有什么区别?</h3>
<p>错误地复制数据会导致引用错误。</p>
<p><strong>回答:</strong></p>
<ul>
<li><strong>浅拷贝</strong>:复制顶级属性,引用嵌套对象。</li>
<li><strong>深层复制</strong>:递归复制所有内容。需要完全数据隔离时需要使用深层复制。</li>
</ul>
<hr>
<h3 id="37-javascript-中的垃圾收集是如何工作的">37.🗑 JavaScript 中的垃圾收集是如何工作的?</h3>
<p>了解内存管理有助于避免泄漏和性能问题。</p>
<p><strong>答:</strong><br>
JS 使用自动垃圾收集。当某个对象不再被引用时,它将变得不可访问,并会被 GC 从内存中删除。</p>
<h2 id="-2025-年每个前端开发人员都应该准备的-40-个-javascript-面试问题-2">💻 2025 年每个前端开发人员都应该准备的 40 个 JavaScript 面试问题 🔥(2)</h2>
<hr>
<h3 id="localstorage38--sessionstorage-和-之间有什么区别cookies"><code>localStorage</code>38. 🌐 、<code>sessionStorage</code>、 和 之间有什么区别<code>cookies</code>?</h3>
<p>了解在何处以及如何安全且适当地存储客户数据是一项关键的前端技能。</p>
<p><strong>回答:</strong></p>
<ul>
<li><code>localStorage</code>:持久存储,最大5MB,不会过期。</li>
<li><code>sessionStorage</code>:临时的,关闭标签时清除。</li>
<li><code>cookies</code>:较小(4KB),随每次请求发送,可供服务器访问。</li>
</ul>
<pre><code>localStorage.setItem("user", "Alice");

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<p>使用 cookie 进行身份验证、<code>localStorage</code>偏好设置和<code>sessionStorage</code>临时数据。</p>
<hr>
<h3 id="39什么是-service-worker">39.💭什么是 Service Worker?</h3>
<p>它是渐进式 Web 应用程序 (PWA) 的支柱。</p>
<p><strong>答:****Service Worker</strong><br>
是 一个在后台运行的 JS 脚本,支持离线访问、推送通知和后台同步。它可以拦截网络请求并缓存资源以供离线使用。</p>
<hr>
<h3 id="40-️-什么是高阶函数">40. 🧗🏻‍♂️ 什么是高阶函数?</h3>
<p>JavaScript 本质上是一门函数式语言。这一概念是许多现代 JS 语言(例如<code>map</code>、<code>filter</code>等)的基础。</p>
<p><strong>回答:</strong></p>
<p>高阶函数是将另一个函数作为参数或返回一个函数的函数。</p>
<pre><code>function repeat(n, action) {
for (let i = 0; i &lt; n; i++) {
    action(i);
}
}
repeat(3, console.log); // Logs 0, 1, 2

</code></pre>
<p>Enter fullscreen mode Exit fullscreen mode</p>
<p>它可以帮助您编写更清晰、可重用的代码,尤其是在函数式编程中。</p>
<hr>
<h2 id="-最后的想法">🎉 最后的想法</h2>
<p>掌握这<strong>40 个 JavaScript 问题,</strong>让你在前端面试中占据显著优势💡。运用它们来编写更简洁的代码,解决更棘手的问题,并给面试官留下深刻印象。</p>
<p>转自:https://mp.weixin.qq.com/s/H0b2y3JRe7xHAY81JP259g</p><br><br>
来源:https://www.cnblogs.com/dc-s/p/18877458
頁: [1]
查看完整版本: 2025年每个前端开发人员都应该准备的 40 个 JavaScript 面试问题