如何通过JavaScript面试:最常问的问题
JavaScript开发者面试不仅仅考察语法,更重要的是对语言运行机制的深入理解。尤其在Node.js中,异步和错误处理是重中之重。本文整理了面试中最常问的10个问题,涵盖初级和中级开发者常见考题。每个问题都附有代码示例和详细解析。
1. 什么是闭包?它有哪些应用场景?
闭包是指即使外部函数执行完毕后,仍能"记住"其词法作用域的函数。这是JavaScript的核心概念之一。
示例:
function createCounter() { let count = 0; return function() { count++; return count; };}
const counter = createCounter();console.log(counter()); // 1console.log(counter()); // 2应用场景:模块封装、函数工厂、记忆化(Memoization)、事件处理,以及循环中的闭包问题(例如setTimeout场景)。
2. Node.js的Event Loop是如何工作的?
Event Loop是让Node.js在单线程下实现非阻塞I/O的机制。它包含多个阶段:定时器(timers)、轮询(poll)、检查(check)和关闭回调(close callbacks)。
微任务示例:
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// 输出: 1, 4, 3, 2为什么这样输出?微任务(Promise)会在当前执行栈清空后、Event Loop进入下一阶段前立即执行。
3. ==和===的区别
==运算符在比较时会进行类型转换,而===则进行严格相等比较(不转换类型)。
console.log(5 == '5'); // true (字符串被转为数字)console.log(5 === '5'); // false (类型不同)console.log(null == undefined); // trueconsole.log(null === undefined); // false面试中常被问到为什么[] == false返回true(因为抽象比较时会转换为原始值)。
4. 什么是原型继承?
在JavaScript中,对象可以通过原型链从其他对象继承属性。每个对象都有内部属性[[Prototype]],可通过__proto__或Object.getPrototypeOf()访问。
示例:
const animal = { eats: true };const rabbit = { jumps: true };
rabbit.__proto__ = animal;
console.log(rabbit.eats); // true (继承自animal)console.log(rabbit.jumps); // true现代写法推荐使用Object.create()或class(本质是原型的语法糖)。
5. JavaScript中的this指向如何确定?
this的值由函数调用时的上下文决定。主要规则如下:
- 全局上下文(浏览器中)指向
window,Node.js中指向global。 - 作为对象方法调用时指向该对象本身。
- 箭头函数中的
this继承自外层函数(词法this)。 - 通过
call/apply/bind调用时指向显式传入的上下文。
示例:
const obj = { name: 'Alice', greet: function() { console.log(this.name); }};
obj.greet(); // Alice
const greet = obj.greet;greet(); // undefined (丢失上下文)
const boundGreet = obj.greet.bind({ name: 'Bob' });boundGreet(); // Bob