一、JavaScript核心概念解析
1.1 变量提升与作用域
在JavaScript中,变量提升(Hoisting)是ES3时代遗留的重要机制。它指变量声明(var)和函数声明会被“提升”到其作用域顶部,但赋值操作不会被提升。
let和const虽也有提升,但存在“暂时性死区”(TDZ),在声明之前访问会报错。上述代码等价于:
作用域链是JavaScript实现词法作用域的核心机制。当访问一个变量时,引擎会从当前作用域开始,逐级向上查找,直到全局作用域。
- 全局作用域(Global Scope)
- 函数作用域(Function Scope)
- 块级作用域(Block Scope):ES6引入,通过
let/const实现
1.2 this指向机制
this的指向是面试高频考点,其值取决于函数的调用方式,而非定义位置。主要规则如下:
独立函数调用时,this指向全局对象(浏览器中为window,Node.js中为global)。严格模式下为undefined。
作为对象方法调用时,this指向该对象。
const fn = obj.getName; fn()会指向全局对象。通过call、apply、bind可显式指定this。
通过new调用构造函数时,this指向新创建的对象实例。
new表达式返回该对象;返回基本类型则忽略,仍返回实例。1.3 闭包(Closure)
闭包是函数与其词法环境的组合。它允许内部函数访问外部函数的变量,即使外部函数已执行完毕。
常见用途:数据私有化、函数柯里化、延迟执行。
常见陷阱:循环中创建闭包时,变量值共享问题。
解决方案:使用let(块级作用域)或IIFE。
1.4 原型与原型链
JavaScript采用基于原型的继承机制。每个对象都有一个隐式原型(__proto__),指向其构造函数的prototype属性;构造函数的prototype对象有constructor属性指回构造函数。
原型链是对象属性查找的路径:当访问对象属性时,若自身无该属性,则沿__proto__向上查找,直至null。
Object.getPrototypeOf(obj)是获取原型的标准方式(避免直接使用__proto__)。二、ES6+ 核心新特性
2.1 let / const 与块级作用域
ES6引入let和const,解决var的变量提升与作用域问题:
- 块级作用域:由
{}界定,避免变量泄露 - 禁止重复声明:同一作用域内不能重复声明同名变量
- 暂时性死区(TDZ):在声明前访问报错
const声明常量,但对象属性可修改(非深冻结)
2.2 解构赋值
从数组或对象中提取值,赋给变量,提升代码简洁性。
undefined错误。2.3 箭头函数
箭头函数不绑定自己的this、arguments、super,而是继承外层作用域。
适用场景:回调函数、简短函数表达式
不适用场景:需要动态this的构造函数、事件处理器(需显式绑定)
2.4 模板字符串与扩展运算符
2.5 Set / Map 数据结构
ES6新增的集合类型,解决对象键只能为字符串的问题。
for...of遍历。2.6 Proxy 与 Reflect
Proxy可拦截并自定义对象操作(如属性读写、函数调用)。
Reflect提供统一的操作对象API,配合Proxy使用更优雅。
三、异步编程与事件循环
3.1 回调函数与回调地狱
早期异步方案,通过函数嵌套实现顺序执行,但易导致代码可读性差(“回调地狱”)。
3.2 Promise
Promise将异步操作表示为状态机(pending → fulfilled / rejected),支持链式调用。
.then()返回新Promise,实现链式;.catch()捕获整个链路的错误。3.3 async / await
ES2017引入的语法糖,使异步代码写法接近同步,提升可读性。
await必须在async函数内;多个独立异步任务可用Promise.all并行执行。3.4 事件循环(Event Loop)机制
浏览器通过事件循环处理异步任务,分为:
- 调用栈(Call Stack):执行同步代码
- 任务队列(Task Queue):宏任务(macrotask),如
setTimeout、setInterval - 微任务队列(Microtask Queue):微任务,如
Promise.then、queueMicrotask
输出顺序:1 → 5 → 3 → 4 → 2
3.5 防抖(Debounce)与节流(Throttle)
防抖:多次触发只执行最后一次(如输入框搜索)
节流:多次触发只执行第一次或每隔n秒执行一次(如滚动加载)
四、JavaScript运行机制
4.1 内存管理与垃圾回收
JavaScript自动管理内存,通过垃圾回收(GC)释放无用对象:
- 标记清除(主流):从根对象出发,遍历所有可达对象,标记存活,清除未标记
- 引用计数:记录对象被引用次数,为0时回收(易导致循环引用问题)
4.2 执行上下文与执行栈
每次函数调用时创建执行上下文(Execution Context),包含:
- 变量对象(VO)/活动对象(AO)
- 作用域链
this值
执行栈(Call Stack)管理上下文生命周期:进入函数→创建上下文→压栈;函数返回→出栈。
4.3 模块化(ESM vs CommonJS)
静态导入,编译时分析依赖,支持Tree Shaking。
动态导入,运行时加载,Node.js传统方案。
五、进阶拓展与实战技巧
5.1 深浅拷贝
structuredClone(obj)(浏览器原生支持)。5.2 高阶函数与函数式编程
高阶函数:接受函数作为参数或返回函数。
5.3 类型系统:TypeScript 与 JSDoc
TypeScript是JavaScript的超集,添加静态类型,提升代码可维护性。
JSDoc可在原生JS中添加类型注解(需配合VS Code等工具)。
5.4 性能优化要点
- 减少重排重绘:批量操作DOM、使用
transform代替top/left - 虚拟DOM:React/Vue等框架的核心优化
- 懒加载:图片、组件按需加载
- Web Worker:将计算密集型任务移至后台线程
- 内存优化:避免全局变量、及时清理事件监听
Performance面板、Lighthouse、Chrome DevTools。