以下是JavaScript常见面试题及解析的整理,帮助您系统准备相关知识点:
问题:什么是闭包?举例说明其用途。
答案:
闭包是能够访问其他函数作用域变量的函数。它使得函数外部可以访问内部变量,常用于封装私有变量或延长变量生命周期。
示例:
function createCounter() {
let count = 0;
return () => count++;
}
const counter = createCounter();
console.log(counter()); // 0
console.log(counter()); // 1
问题:解释JavaScript中的原型链。
答案:
每个对象都有一个原型对象,通过__proto__
属性连接,形成链式结构。访问属性时,若对象自身不存在,则沿原型链向上查找,直到null
。
示例:
function Person(name) { this.name = name; }
Person.prototype.sayHi = function() { console.log(`Hi, ${this.name}`); };
const p = new Person('Alice');
p.sayHi(); // 调用原型方法
问题:箭头函数和普通函数有什么区别?
答案:
this
,继承外层上下文。 new
调用,无prototype
属性。 arguments
或通过剩余参数(...args
)获取。问题:宏任务和微任务的执行顺序是怎样的?
答案:
setTimeout
、setInterval
、I/O。 Promise.then
、MutationObserver
。执行顺序:每轮循环先清空微任务队列,再执行一个宏任务。
示例:
console.log('start');
setTimeout(() => console.log('timeout'), 0);
Promise.resolve().then(() => console.log('promise'));
console.log('end');
// 输出顺序:start → end → promise → timeout
问题:ES6的class如何实现继承?
答案:class
通过extends
和super
实现继承,本质是原型链的语法糖。
示例:
class Animal {
constructor(name) { this.name = name; }
speak() { console.log(`${this.name} makes noise`); }
}
class Dog extends Animal {
speak() { console.log(`${this.name} barks`); }
}
const dog = new Dog('Rex');
dog.speak(); // Rex barks
答案:
this
指向全局(严格模式为undefined
)。 this
指向调用对象。 call
/apply
/bind
指定this
。 this
指向新实例。 this
。问题:如何用Promise解决回调地狱?
答案:
Promise通过链式调用(.then()
)管理异步流程,async/await
进一步简化代码:
fetchData()
.then(data => process(data))
.catch(err => console.error(err));
// async/await
async function handleData() {
try {
const data = await fetchData();
process(data);
} catch (err) {
console.error(err);
}
}
问题:如何解决跨域问题?
答案:
Access-Control-Allow-Origin
头。 <script>
标签,通过回调函数获取数据。 答案:
递归拷贝对象,处理循环引用(使用WeakMap):
function deepClone(obj, map = new WeakMap()) {
if (typeof obj !== 'object' || obj === null) return obj;
if (map.has(obj)) return map.get(obj);
const clone = Array.isArray(obj) ? [] : {};
map.set(obj, clone);
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], map);
}
}
return clone;
}
答案:
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
function throttle(fn, delay) {
let last = 0;
return (...args) => {
const now = Date.now();
if (now - last >= delay) {
fn.apply(this, args);
last = now;
}
};
}
import/export
)与CommonJS差异。 通过理解以上核心概念,结合实际代码示例,可系统掌握JavaScript面试要点。建议结合手写代码实践(如实现Promise、bind等)加深理解。