JavaScript面试题精选
引言
JavaScript是现代Web开发的支柱。无论您是在准备面试还是复习知识,这里有10个经常被问到的JavaScript问题,配有简洁准确的答案。
1. var、let 和 const 有什么区别?
var 具有函数作用域,允许重新声明
let 和 const 具有块级作用域
let 是可变的;const 是不可变的(不能重新赋值)
- // var 示例
- var x = 1;
- var x = 2; // 允许重新声明
- // let 示例
- let y = 1;
- // let y = 2; // 错误:不能重新声明
- // const 示例
- const z = 1;
- // z = 2; // 错误:不能重新赋值
2. JavaScript中的闭包是什么?
闭包是一个函数,它记住了其外部词法作用域中的变量,即使外部函数已经执行完毕。
- function outer() {
- let count = 0;
- return function inner() {
- return ++count;
- };
- }
- const counter = outer();
- console.log(counter()); // 1
- console.log(counter()); // 2
- console.log(counter()); // 3
3. == 和 === 有什么区别?
== 检查相等性并进行类型转换
=== 检查相等性但不进行类型转换(严格相等)
- "5" == 5 // true(类型转换后相等)
- "5" === 5 // false(类型不同)
- null == undefined // true
- null === undefined // false
4. 什么是事件委托?
事件委托是一种技术,将单个事件监听器添加到父元素,以处理来自其子元素的事件,使用 event.target。
对性能和动态内容很有用。
- // 传统方式:为每个按钮添加事件监听器
- document.querySelectorAll('.btn').forEach(btn => {
- btn.addEventListener('click', handleClick);
- });
- // 事件委托:在父元素上添加一个监听器
- document.querySelector('.container').addEventListener('click', (e) => {
- if (e.target.classList.contains('btn')) {
- handleClick(e);
- }
- });
5. JavaScript中的Promise是什么?
Promise是一个表示异步操作最终完成或失败的对象。
- let promise = new Promise((resolve, reject) => {
- // 异步任务
- setTimeout(() => {
- const success = Math.random() > 0.5;
- if (success) {
- resolve('操作成功!');
- } else {
- reject('操作失败!');
- }
- }, 1000);
- });
- promise
- .then(result => console.log(result))
- .catch(error => console.error(error));
6. JavaScript中的提升(Hoisting)是什么?
提升意味着变量和函数声明在执行代码之前被移动到其作用域的顶部。
var 被提升(但未初始化)
let 和 const 被提升但保持在暂时性死区
- // 函数提升
- hoistedFunction(); // "函数被提升了"
- function hoistedFunction() {
- console.log("函数被提升了");
- }
- // 变量提升
- console.log(x); // undefined(不是错误)
- var x = 5;
- // let 和 const 的暂时性死区
- // console.log(y); // 错误:Cannot access 'y' before initialization
- let y = 10;
7. null 和 undefined 有什么区别?
undefined:声明了变量但未赋值
null:有意表示没有值
- let a; // undefined
- let b = null; // null
- console.log(typeof a); // "undefined"
- console.log(typeof b); // "object"
8. 解释JavaScript中的 this 关键字
this 指向执行当前函数的对象:
在方法中:对象本身
单独使用:window(非严格模式)
在箭头函数中:继承自父作用域
- // 在对象方法中
- const obj = {
- name: '张三',
- greet() {
- console.log(`你好,我是${this.name}`);
- }
- };
- obj.greet(); // "你好,我是张三"
- // 在箭头函数中
- const obj2 = {
- name: '李四',
- greet: () => {
- console.log(`你好,我是${this.name}`);
- }
- };
- obj2.greet(); // "你好,我是undefined"
- // 在构造函数中
- function Person(name) {
- this.name = name;
- }
- const person = new Person('王五');
- console.log(person.name); // "王五"
9. JavaScript中的事件循环是什么?
事件循环通过管理调用栈和任务队列来处理异步回调,实现非阻塞行为。
- console.log('1'); // 同步任务
- setTimeout(() => {
- console.log('2'); // 异步任务
- }, 0);
- Promise.resolve().then(() => {
- console.log('3'); // 微任务
- });
- console.log('4'); // 同步任务
- // 输出顺序:1, 4, 3, 2
10. map() 和 forEach() 有什么区别?
map() 返回一个新数组
forEach() 为每个项目执行函数但返回 undefined
- const numbers = [1, 2, 3];
- // map() 返回新数组
- const doubled = numbers.map(x => x * 2);
- console.log(doubled); // [2, 4, 6]
- // forEach() 不返回任何值
- const result = numbers.forEach(x => x * 2);
- console.log(result); // undefined
- // forEach() 用于副作用
- numbers.forEach(x => console.log(x * 2)); // 2, 4, 6
总结
掌握这些核心JavaScript概念可以显著提升您在技术面试中的信心。建议练习编写这些示例的代码,以加深理解。
面试准备建议
理解概念:不仅要记住答案,更要理解背后的原理
动手实践:在控制台中运行这些代码示例
举一反三:思考这些概念在实际项目中的应用
持续学习:JavaScript生态系统不断发展,保持学习
