惰性载入表示函数执行的分支仅会发生一次。有两种实现惰性载入的方式:
一、在函数被调用时再处理函数
在第一次调用的过程中,该函数会被覆盖为另外一个按合适方式执行的函数,这样任何对原函数的调用都不用再经过执行的分支了。
function createXHR () {
if (typeof XMLHttpRequest != 'undefined') {
createXHR = function () {
return new XMLHttpRequest()
}
} else if (typeof ActiveXObject != 'undefined') {
createXHR = function () {
if (typeof arguments.callee.activeXString != 'string') {
let versions = ['MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'], i, len
for (i = 0, len = versions.length; i < len; i++) {
try {
new ActiveXObject(versions[i])
arguments.callee.activeXString = versions[i]
break
} catch (ex) {
// skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString)
}
} else {
createXHR = function () {
throw new Error('No XHR object available.')
}
}
return createXHR()
}
在这个惰性载入的createXHR()中,if语句的每一个分支都会为createXHR变量赋值,有效覆盖了原有的函数。最后一步便是调用新赋的函数。下一次调用createXHR()的时候,就会直接调用被分配的函数,这样就不用再次执行if语句了。
二、在声明函数时就指定适当的函数
这样,第一次调用函数时就不会损失性能了,而在代码首次加载时会损失一点性能。
const createXHR = (function () {
if (typeof XMLHttpRequest != 'undefined') {
return function () {
return new XMLHttpRequest()
}
} else if (typeof ActiveXObject != 'undefined') {
return function () {
if (typeof arguments.callee.activeXString != 'string') {
let [versions, i, len] = [['MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'], 0, 0]
for (i = 0, len = versions.length; i < len; i++) {
try {
new ActiveXObject(versions[i])
arguments.callee.activeXString = versions[i]
break
} catch (ex) {
// skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString)
}
} else {
return function () {
throw new Error('No XHR object available.')
}
}
})()
// 使用方法
let xhr = createXHR()
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
console.log(xhr.responseText)
} else {
console.log('Request was unsuccessful: ' + xhr.status)
}
}
}
xhr.onprogress = function (event) {
if (event.lengthComputable) {
console.log('Received ' + event.loaded + ' of ' + event.total + ' bytes.')
}
}
xhr.open('GET', 'example.txt')
xhr.send(null)