javascript无原生数组懒加载,但可通过生成器函数实现惰性求值、proxy代理缓存计算、分页加载模拟dom懒加载、promise包装异步项等方式按需加载。

JavaScript 中没有原生的“数组懒加载”机制,但可以通过封装逻辑模拟懒加载行为——即延迟计算、按需获取或分批加载数组元素,避免一次性初始化大量数据或执行高开销操作。
用生成器函数(Generator)实现惰性求值
生成器函数天然支持暂停/恢复执行,适合构建可迭代但不立即执行的数组逻辑。它不真正“加载数组”,而是按需产出值。
例如,生成一个超大范围的数字序列,但只在遍历时计算:
function* range(start, end) {
for (let i = start; i // 使用时才逐个计算,不占用内存存整个数组
for (const num of range(0, 1000000)) {
if (num > 10) break;
console.log(num); // 只执行前11次
}这种模式适用于:数值序列、树遍历、无限流、I/O 或计算密集型项的延迟生成。
用 Proxy 拦截访问,实现按需计算
对一个“虚拟数组”对象使用 Proxy,在 get 拦截中动态计算并缓存指定索引的值,避免预分配内存。
示例:一个延迟计算平方值的“伪数组”:
const lazyArray = new Proxy(
{ cache: new Map(), length: 1000 },
{
get(target, prop) {
if (prop === 'length') return target.length;
if (Number.isInteger(Number(prop))) {
const index = Number(prop);
if (index = target.length) return undefined;
if (!target.cache.has(index)) {
target.cache.set(index, index * index); // 模拟耗时计算
}
return target.cache.get(index);
}
}
}
);
<p>console.log(lazyArray[5]); // 计算并缓存 25
console.log(lazyArray[10]); // 计算并缓存 100
console.log(lazyArray[5]); // 直接返回缓存值</p>适合场景:稀疏访问、计算成本高、索引空间大但实际访问少。
分页/切片式加载(模拟前端列表懒加载)
对于真实 DOM 渲染场景(如长列表),所谓“数组懒加载”通常指:初始只加载首屏数据,滚动时再加载下一批。这时数组本身是逐步拼接的。
- 维护一个基础数组(如
items = [])和加载状态(isLoading、hasMore) - 监听滚动/IntersectionObserver 触发
loadMore() -
loadMore发起请求,拿到新数据后items.push(...newItems) - 渲染层仅绑定当前
items,无需修改数组结构
关键不是数组本身懒,而是数据获取与渲染协同按需进行。可配合 slice(start, end) 渲染视窗内片段提升性能。
结合 Promise 实现异步懒加载项
当数组元素依赖异步资源(如 API、文件读取),可用 Promise 包装每个位置,首次访问时触发加载并缓存结果:
class LazyAsyncArray {
constructor(fetcher, length) {
this.fetcher = fetcher; // (index) => Promise<value>
this.length = length;
this.cache = new Map();
}
<p>async get(index) {
if (index = this.length) return undefined;
if (this.cache.has(index)) return this.cache.get(index);</p>
<pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">const value = await this.fetcher(index);
this.cache.set(index, value);
return value;} }
// 使用
const apiArray = new LazyAsyncArray(
idx => fetch(/api/items/${idx}
// 按需调用,不提前发起所有请求 const item = await apiArray.get(42);
这种方式把“加载时机”从初始化阶段推迟到实际读取时刻,有效降低首屏压力。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











