Appearance
JavaScript 核心概念深度解析
静态作用域和动态作用域
- JavaScript 采用词法作用域(静态作用域),函数作用域在定义时就确定
- 动态作用域中,函数作用域在调用时才确定
执行上下文与变量对象
当执行可执行代码时,会创建对应的执行上下文,包含三个核心属性:
- 变量对象(VO)
- 作用域链
- this
函数上下文
- 函数上下文中使用活动对象(AO) 表示变量对象
- AO 在进入函数上下文时创建,通过
arguments
属性初始化 - AO 变化过程:
- 进入执行上下文:添加形参、函数声明、变量声明
- 代码执行阶段:修改变量值
js
function foo(a) {
var b = 2;
function c() {}
var d = function() {};
b = 3;
}
foo(1);
// 进入执行上下文时AO:
AO = {
arguments: {0: 1, length: 1},
a: 1,
b: undefined,
c: reference to function c(){},
d: undefined
}
// 代码执行后AO:
AO = {
arguments: {0: 1, length: 1},
a: 1,
b: 3,
c: reference to function c(){},
d: reference to FunctionExpression "d"
}
作用域链
- 查找变量时从当前上下文的变量对象开始,沿父级执行上下文逐级查找
- 作用域链是由多个执行上下文的变量对象构成的链表
js
function foo() {
function bar() {
// bar作用域链:[bar.AO, foo.AO, global.VO]
}
}
函数参数传递
- ECMAScript 中所有函数参数都是按值传递
- 基本类型:传递值的副本
- 引用类型:传递引用的副本(共享传递)
js
var obj = { value: 1 };
function foo(o) {
o = 2; // 修改引用副本
}
foo(obj);
console.log(obj.value); // 1(原对象未改变)
手写核心方法
实现 call
js
Function.prototype.call2 = function (context, ...args) {
context = context || window;
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
};
实现 bind
js
Function.prototype.myBind = function (context) {
const self = this;
return function (...args) {
return self.apply(context, args);
};
};
实现 new
js
function myNew(Fn, ...args) {
const obj = Object.create(Fn.prototype);
const result = Fn.apply(obj, args);
return result instanceof Object ? result : obj;
}
AJAX vs Fetch
特性 | AJAX (XMLHttpRequest) | Fetch |
---|---|---|
设计 | 回调函数 | Promise |
API 设计 | 集中式 | 模块化(Request/Response/Headers) |
数据流 | 不支持分块读取 | 支持 Stream 分块读取 |
CORS | 需手动处理 | 默认不发送 cookies |
let 底层实现
- 编译阶段:扫描函数体,为 let 变量生成初始词法环境
- 执行上下文:进入块级作用域创建新词法环境
- 绑定变量值:运行时在词法环境中搜索变量
- 块级作用域:创建子遮蔽环境实现作用域隔离
垃圾回收机制
引用计数
- 优点:立即回收垃圾
- 缺点:循环引用问题,计数器占用空间
标记清除
- 标记所有对象为垃圾(0)
- 从根对象遍历,标记可达对象(1)
- 清除标记为 0 的对象
- 优点:实现简单
- 缺点:内存碎片
分代回收
- 新生代:新创建对象,回收频率高
- 老生代:长期存活对象,回收频率低
函数式编程核心
- 纯函数:相同输入 => 相同输出,无副作用js
function add(a, b) { return a + b; }
- 不可变性:数据创建后不可修改js
const newArr = [...arr, newItem];
- 高阶函数:函数作为参数或返回值js
function multiplier(factor) { return (num) => num * factor; }
- 函数组合:js
const process = compose(func1, func2, func3);
发布订阅 vs 观察者模式
特性 | 发布订阅 | 观察者 |
---|---|---|
耦合度 | 完全解耦 | 相互耦合 |
通信方式 | 消息通道 | 直接调用 |
扩展性 | 高(多发布/订阅者) | 低 |
精度丢失问题
js
0.1 + 0.2 !== 0.3; // true
9007199254740991 + 1; // 精度丢失
原因:浮点数二进制表示存在近似值
WeakMap vs Map
特性 | WeakMap | Map |
---|---|---|
Key 类型 | 仅对象 | 任意值 |
引用类型 | 弱引用 | 强引用 |
垃圾回收 | 自动回收 | 不回收 |
可枚举 | 否 | 是 |
小程序双线程架构
- 渲染层:WebView 渲染界面
- 逻辑层:JsCore 线程运行 JS 脚本 优势:避免 JS 执行阻塞渲染
前端工程化核心
- 模块化:代码按功能划分
- 规范化:统一代码风格
- 自动化:构建/测试/部署
- 组件化:高复用 UI 组件
重绘 vs 回流
重绘 | 回流 | |
---|---|---|
触发条件 | 外观变化 | 布局变化 |
性能影响 | 较小 | 较大 |
优化建议 | 避免频繁样式修改 | 批量 DOM 操作 |
setTimeout vs requestAnimationFrame
setTimeout | requestAnimationFrame | |
---|---|---|
执行时机 | 指定时间后 | 下一帧开始前 |
主线程 | 阻塞 | 不阻塞 |
后台运行 | 继续执行 | 暂停 |
适用场景 | 通用定时 | 动画优化 |
script 加载策略
正常加载 | async | defer | |
---|---|---|---|
HTML 解析 | 暂停 | 并行 | 并行 |
执行顺序 | 顺序执行 | 下载完立即执行 | HTML 解析完后顺序执行 |
使用建议 | - | 独立脚本 | 依赖 DOM 的脚本 |
内存泄漏场景
- 意外全局变量js
function leak() { temp = "leak"; }
- 未清除定时器js
setInterval(() => {...}, 1000);
- DOM 引用未释放js
const element = document.getElementById("my-element"); // 未在不需要时解除引用
- 闭包滥用js
function outer() { const bigData = new Array(1000000); return function inner() { console.log(bigData.length); }; }
Vite 为何启动快
- 开发环境:直接使用 ES6 Module,无需打包
- 按需编译:仅编译当前请求的模块
- Esbuild 预构建:极速的依赖预构建
Vue vs React 对比
Vue | React | |
---|---|---|
模板系统 | 基于 HTML 的模板 | JSX |
更新粒度 | 组件级 | 从根节点调度 |
响应式 | Proxy 拦截 | setState 触发 |
渲染方式 | 递归 | 可中断循环 |
模块化概念
术语 | 含义 |
---|---|
Module | 源码文件(webpack 中一切皆模块) |
Chunk | 多个模块合并(entry/import/splitChunk) |
Bundle | 最终输出文件 |
前端打包必要性
- 性能优化:Tree-Shaking/压缩/合并
- 语法转换:TS/ES6+/SCSS → 浏览器兼容
- 工程能力:Lint/测试/CI/CD 集成
项目构建要素
mermaid
graph TD
A[代码仓库] --> B[框架选择]
B --> C[目录规范]
C --> D[构建工具]
D --> E[代码规范]
E --> F[预提交检查]
F --> G[单元测试]
G --> H[CI/CD]
H --> I[文档系统]
开发环境标识
环境 | 全称 | 用途 |
---|---|---|
DEV | Development | 开发 |
SIT | System Integration Test | 系统整合测试 |
UAT | User Acceptance Test | 用户验收测试 |
PROD | Production | 生产环境 |
循环方法对比
方法 | 可中断 | 遍历内容 | 适用对象 |
---|---|---|---|
forEach | ❌ | 值 | Array |
for...in | ✅ | 键 | Object/Array |
for...of | ✅ | 值 | Array/Map/Set |
数据类型细节
undefined
:变量声明但未初始化null
:空对象指针
递减操作符
js
let a = 5;
let b = a-- + 2; // b=7, a=4(先计算后递减)
let c = --a + 2; // a=3, c=5(先递减后计算)