简介
惰性函数是一种设计模式,主要用于延迟计算某些复杂对象的创建,直到这些对象实际需要使用时才进行创建。这样可以提高性能,因为一些不常用的功能不会在脚本加载时立即执行,从而减少资源消耗。
惰性函数的基本原理
惰性函数的本质是函数重写。在函数第一次被调用时,它将自身重写为一个不同的函数,通常是返回一个预先计算的结果。这样,后续的调用就不会再执行原来的计算过程,而是直接返回第一次计算的结果。
惰性函数的实现
惰性函数通常通过闭包来实现。闭包允许函数记住并访问其创建时所在作用域中的变量,即使函数在一个不同的作用域被调用。
代码示例
惰性求值
- 创建一个惰性求值函数,它只在第一次调用时计算斐波那契数列的第 n 项,并将结果存储起来,后续调用直接返回存储的结果
- fibonacci 函数返回一个惰性函数 lazyFib,它只有在第一次调用 lazyFib(n) 时才会计算斐波那契数列的第 n 项。后续的调用会直接返回存储的结果
function fibonacci() {
let memo = [0, 1];
// 惰性函数,用于计算斐波那契数列的第 n 项
function fib(n) {
if (memo[n] != null) {
return memo[n];
}
memo[n] = fib(n - 1) + fib(n - 2);
return memo[n];
}
// 重写函数,使其返回 fib 函数
return function(n) {
if (typeof memo[n] !== 'number') {
memo[n] = fib(n);
}
return memo[n];
};
}
// 创建惰性函数实例
const lazyFib = fibonacci();
console.log(lazyFib(10)); // 计算 Fibonacci 10
console.log(lazyFib(10)); // 直接返回结果,不再计算
惰性载入
- 创建一个函数来检测浏览器是否支持某个特性。如果支持,则重写函数以直接返回 true;如果不支持,则重写函数以直接返回 false
- createXHR 函数在第一次调用时会检查浏览器是否支持 XMLHttpRequest 或 ActiveXObject。根据检查结果,函数会重写自身,以便后续调用可以快速返回正确的结果。
function createXHR() {
if (typeof XMLHttpRequest != 'undefined') {
// 重写函数以直接返回 new XMLHttpRequest()
createXHR = function() {
return new XMLHttpRequest();
};
} else if (typeof ActiveXObject != 'undefined') {
// 重写函数以直接返回 new ActiveXObject()
createXHR = function() {
if (typeof arguments.callee.activeXString != 'string') {
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"];
for (var i = 0, len = versions.length; i < len; i++) {
try {
var xhr = new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
return xhr;
} catch (ex) {
// skip
}
}
throw new Error("No XHR object available.");
}
return new ActiveXObject(arguments.callee.activeXString);
};
} else {
// 重写函数以直接返回 null
createXHR = function() {
return null;
};
}
return createXHR();
}
// 使用惰性载入函数
var xhr = createXHR();
if (xhr) {
// 执行 XHR 相关操作
}