惰性函数
定义
惰性函数解决了这类问题:
第一次调用这个方法时,返回一个值;后面每次调用都返回第一次计算出来的值。
举个例子:
例子来自文章
我们现在需要写一个 foo 函数,这个函数返回首次调用时的 Date 对象,注意是首次。
可以轻易的想到几种方法
全局变量法
let t
const foo = ()=> {
if(t) return t
t = new Date;
return t
}
这种方法有两个缺点:污染全局变量、每次都需要做一个判断(if(t)
)
看到「污染全局变量」我们自然而然的就会想到用闭包来处理
闭包
const foo = ()=>{
let t;
return function(){
if(t)return t
t = new Date()
return t
}
}
这样做之后,污染全局变量的问题解决了,但是每次都需要判断还是没被解决
还有其他的实现方案吗?
函数对象法
js 里函数也是对象,所以可以把变量挂在函数上
const foo = () =>{
if(foo.t) return foo.t
foo.t = new Date()
return foo.t
}
又是一种解决方案,等等,这不是和闭包法一样嘛,污染全局变量的问题解决了,但是每次都需要判断还是没被解决。
那有没有什么做法能不需要判断呢;答案就是惰性函数。在运行一次后,就把自身改变了
惰性函数
const foo = ()=>{
let t = new Date()
foo = () => t
return foo()
}
仅第一次运行的时候执行了new Date()
,以后再也不会执行了。
应用场景
一个典型的「每次都需要进行条件判断,其实只需要判断一次」的场景如下:
我们有一个获取打印机列表的方法:在 Mac 系统是getMacPrinterList
在 Windows 系统是 getWinPrinterList
(假设不用考虑其他系统)
以前我们通常这么写
function getPrinterList (){
let isMac = /macintosh|mac os x/i.test(navigator.userAgent)
if(isMac){
return getMacPrinterList()
}else{
return getWinPrinterList()
}
}
使用惰性函数,我们可以这么写
function getPrinterList (){
let isMac = /macintosh|mac os x/i.test(navigator.userAgent)
if(isMac){
getPrinterList = getMacPrinterList
}else{
getPrinterList = getWinPrinterList
}
return getPrinterList()
}
Comments