JavaScript面试题汇总:高频考点与答案解析

在前端开发领域,JavaScript作为核心语言,其面试题覆盖了从基础语法到高级特性的广泛范围。本文ZHANID工具网将系统梳理JavaScript高频面试考点,结合权威资料与典型案例,为开发者提供清晰的解题思路与知识框架。

一、数据类型与类型检测

1. 数据类型分类

JavaScript包含7种原始类型1种引用类型

  • 原始类型stringnumberbooleannullundefinedsymbol(ES6新增,唯一标识符)、bigint(ES2020新增,大整数)。

  • 引用类型object(包括arrayfunctiondateregexp等)。

示例

typeof"hello";//"string"
typeofnull;//"object"(历史遗留问题)
typeofSymbol();//"symbol"

2. 类型检测方法

方法 特点 示例
typeof 返回数据类型的字符串表示,但对null和引用类型区分有限typeof []"object"
instanceof 检测对象是否为某构造函数的实例,仅适用于引用类型[] instanceof Arraytrue
Object.prototype.toString.call() 精确判断所有类型,返回[object Type]格式字符串Object.prototype.toString.call(42)"[object Number]"

示例

//判断数组类型
constisArray=(arr)=>Object.prototype.toString.call(arr)==='[objectArray]';
isArray([]);//true

二、变量提升与作用域

1. 变量提升机制

  • var:声明提升至作用域顶部,初始值为undefined

  • let/const:存在暂时性死区(TDZ),未初始化前访问会报错。

示例

console.log(a);//undefined(var提升)
vara=1;

console.log(b);//ReferenceError(let未初始化)
letb=2;

2. 作用域链

JavaScript通过词法作用域查找变量,从当前作用域逐级向上查找至全局作用域。

示例

functionouter(){
constouterVar='outer';
functioninner(){
console.log(outerVar);//访问外部作用域变量
}
inner();
}
outer();//"outer"

三、闭包与高阶函数

1. 闭包的定义与应用

闭包是函数与其词法环境的组合,常用于数据封装、模块化及回调函数。

示例

functioncreateCounter(){
letcount=0;
returnfunction(){
count++;
returncount;
};
}
constcounter=createCounter();
counter();//1
counter();//2

2. 高阶函数

高阶函数是接收函数作为参数或返回函数的函数,典型应用包括柯里化、防抖与节流。

柯里化(Currying)

将多参数函数转换为单参数函数序列。

functioncurryAdd(a){
returnfunction(b){
returna+b;
};
}
constadd5=curryAdd(5);
add5(3);//8

防抖(Debounce)

事件触发后延迟执行,避免重复触发。

functiondebounce(fn,delay){
lettimer;
returnfunction(...args){
clearTimeout(timer);
timer=setTimeout(()=>fn.apply(this,args),delay);
};
}

节流(Throttle)

限制事件在一定时间内仅触发一次。

functionthrottle(fn,delay){
letlast=0;
returnfunction(...args){
constnow=Date.now();
if(now-last>delay){
fn.apply(this,args);
last=now;
}
};
}

四、原型与继承

1. 原型链机制

每个对象都有__proto__属性指向其构造函数的prototype,形成原型链。

示例

functionPerson(name){
this.name=name;
}
Person.prototype.sayHello=function(){
console.log(`Hello,${this.name}`);
};

constp=newPerson('Alice');
p.sayHello();//"Hello,Alice"

2. 继承实现方式

方式 特点
原型链继承 子类原型指向父类实例,共享父类引用属性
构造函数继承 父类构造函数通过call/apply调用,避免引用共享但无法继承原型方法
组合继承 结合原型链与构造函数继承,解决引用共享问题
ES6类继承 使用classextends语法糖,底层仍为原型链

示例(ES6类继承)

classParent{
constructor(name){
this.name=name;
}
sayHello(){
console.log(`Hello,${this.name}`);
}
}

classChildextendsParent{
constructor(name,age){
super(name);
this.age=age;
}
}

constc=newChild('Bob',18);
c.sayHello();//"Hello,Bob"

五、异步编程

1. 事件循环(Event Loop)

JavaScript为单线程语言,通过任务队列处理异步任务:

  • 宏任务scriptsetTimeoutsetInterval、I/O。

  • 微任务Promise.thenMutationObserver

执行顺序
宏任务 → 微任务 → 渲染 → 宏任务 → ...

示例

console.log('1');//同步任务
setTimeout(()=>console.log('2'),0);//宏任务
Promise.resolve().then(()=>console.log('3'));//微任务
//输出:1→3→2

2. Promise与Async/Await

  • Promise:解决回调地狱,支持链式调用。

  • Async/Await:基于Promise的语法糖,使异步代码更接近同步风格。

示例

functionfetchData(){
returnnewPromise((resolve)=>{
setTimeout(()=>resolve('Data'),1000);
});
}

asyncfunctiongetData(){
console.log('Start');
constdata=awaitfetchData();
console.log(data);//"Data"
}
getData();

六、数组与对象操作

1. 数组去重

方法 特点
Set 利用Set数据结构的唯一性
filter+indexOf 遍历数组并过滤重复项
reduce 递归累积唯一值

示例

//Set去重
constarr=[1,2,2,3];
constuniqueArr=[...newSet(arr)];//[1,2,3]

2. 深拷贝与浅拷贝

方法 特点
浅拷贝 仅复制第一层属性(如Object.assign、展开运算符...
深拷贝 递归复制所有层级(如JSON.parse(JSON.stringify(obj))structuredClone

示例

//深拷贝(兼容性方案)
functiondeepClone(obj){
if(obj===null||typeofobj!=='object')returnobj;
constclone=Array.isArray(obj)?[]:{};
for(constkeyinobj){
clone[key]=deepClone(obj[key]);
}
returnclone;
}

七、性能优化与内存管理

1. 内存泄漏常见原因

  • 意外全局变量:未声明的变量自动挂载至window

  • 闭包引用:闭包中未释放的外部变量。

  • 未清理的定时器/事件监听:如setInterval未调用clearInterval

示例

//内存泄漏示例
functionleak(){
constdata=newArray(1e6).fill('data');//大数组
returnfunction(){
console.log(data[0]);//闭包引用data
};
}
constleakFunc=leak();
//leakFunc未被释放时,data无法被垃圾回收

2. 垃圾回收机制

JavaScript采用标记-清除算法,通过标记不可达对象并回收其内存。开发者需避免手动管理内存,但需注意减少不必要的引用。

八、浏览器兼容性与安全

1. 跨域解决方案

方案 适用场景
CORS 服务端设置Access-Control-Allow-Origin响应头
JSONP 仅支持GET请求,利用标签无跨域限制
Nginx反向代理 通过代理服务器转发请求,隐藏真实域名

示例(CORS)

//服务端设置响应头
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Methods','GET,POST');

2. XSS攻击防御

  • 输入过滤:对用户输入进行转义或过滤。

  • CSP策略:通过Content-Security-Policy限制资源加载来源。

示例

九、模块化与ES6特性

1. ES Modules

  • 导出exportexport default

  • 导入importimport * as

示例

//math.js
exportconstadd=(a,b)=>a+b;
exportdefaultfunctionmultiply(a,b){returna*b;};

//main.js
import{add}from'./math.js';
importmultiplyfrom'./math.js';

2. Symbol与BigInt

  • Symbol:唯一标识符,避免属性名冲突。

  • BigInt:表示大整数,解决Number精度限制。

示例

constid=Symbol('id');
constbigNum=9007199254740991n;//BigInt字面量

十、综合案例解析

案例1:实现一个事件委托函数

functioneventDelegate(parent,selector,eventType,handler){
parent.addEventListener(eventType,(e)=>{
lettarget=e.target;
while(target!==parent){
if(target.matches(selector)){
handler.call(target,e);
break;
}
target=target.parentNode;
}
});
}

//使用示例
document.querySelector('ul').addEventListener('click',(e)=>{
if(e.target.tagName==='LI'){
console.log('Clicked:',e.target.textContent);
}
});

案例2:实现一个Promise.all

functionpromiseAll(promises){
returnnewPromise((resolve,reject)=>{
constresults=[];
letcompleted=0;
promises.forEach((promise,index)=>{
Promise.resolve(promise)
.then((value)=>{
results[index]=value;
completed++;
if(completed===promises.length)resolve(results);
})
.catch(reject);
});
});
}

总结

JavaScript面试题覆盖了语言核心特性、异步编程、浏览器机制及性能优化等多个维度。开发者需深入理解数据类型、作用域、原型链、异步模型等基础概念,同时掌握闭包、高阶函数、模块化等高级特性。通过系统梳理高频考点与典型案例,可显著提升面试通过率与代码质量。

发布于 2025-09-12 23:43:51
分享
海报
168
上一篇:站长如何部署PWA 渐进式Web应用提升访问体验 下一篇:电路仿真软件有哪些:5款免费且好用的电子电路仿真软件推荐
目录

    忘记密码?

    图形验证码