缓存数组长度和对象属性可显著提升性能;JavaScript引擎循环中反复访问arr.length或obj.prop会触发起作用域链或原型链查找,尤其大数组或深层嵌套时开销明显。

直接缓存数组长度和对象属性,能显著减少每次迭代的查找开销。JavaScript 引擎在循环中反复访问 arr.length 或 obj.prop 时,会触发起码一次作用域链或原型链查找,尤其在大数组或深层嵌套对象中,这种重复操作会明显拖慢执行速度。
缓存数组长度,避免重复读取
每次判断 i 都要重新获取 length 属性,而该值在循环中恒定不变。
- 优化前:
for (let i = 0; i → 每轮都查一次length - 优化后:
for (let i = 0, len = arr.length; i → 只查一次,后续用局部变量len - 对超万级数组,性能提升可达 10%–25%,尤其在旧版引擎或严格模式下更明显
用局部变量代替深层对象访问
若循环体中频繁访问如 data.items[0].user.profile.name 这类长路径,每次都要逐层解析属性。
- 把稳定路径提前解构或赋值:
const profile = data.items[0].user.profile;,再在循环里用profile.name - 对 DOM 元素集合也适用:先缓存
const imgs = document.querySelectorAll('img');,再用const doc = document;替代循环内多次写document.title - 避免在
for内部调用 getter 方法(如el.offsetLeft),它们可能触发重排,应提前读取并缓存
倒序循环 + 下标直取,进一步减少查找
利用 JavaScript 中 undefined 的宽松判定,可省去长度缓存变量,同时规避 .length 查找。
- 写法:
for (let i = arr.length; i--; ) { console.log(arr[i]); } - 原理:条件表达式
i--自动转为布尔值(非零为 true),递减动作与判断合并,且只在开头查一次length - 注意:适用于不需要正向索引逻辑的场景,比如仅遍历、映射或销毁操作;若需
i值参与计算,仍推荐显式缓存
配合预分配提升写入效率
如果循环中要构建新数组,避免用 push() 动态扩容,改用预设长度+下标赋值。
- 低效:
const result = []; for (...) result.push(compute(item)); - 高效:
const result = new Array(arr.length); for (let i = 0, len = arr.length; i - 原因:
push()在内部可能触发多次内存重分配,而预分配让 V8 等引擎能提前规划内存布局










