在编程语言理论中,惰性求值(英语:LazyEvaluation),又译为惰性计算,惰性求值,又称call-by-need),是一个概念在计算机编程,其目的是尽量减少计算机必须做的工作。它有两个相关而又截然不同的含义,可以表示为“惰性求值”和“最小化求值”。除了提高性能,惰性计算最重要的好处是可以构造一个**数据类型。看到函数式语言的惰性求值,想用JavaScript写一个最小的实现,加深对惰性求值的理解。使用两种方法,在不到80行的时间内实现了对基本数组的惰性求值。如何实现惰性求值每次求值不返回一个值,而是返回一个包含计算参数的求值函数,每次要使用该值时都会计算该值。当有多个懒操作时,就形成了一个求值函数链。每个评估函数对前一个评估函数进行评估并返回一个值。***当计算函数终止时,返回一个终止值。具体实现判断评估函数终止。每个评估函数都会返回各种数据,因此必须以唯一的值作为判断流程是否完成的标志。碰巧Symbol()创建了一个新的符号,其值不等于任何其他值。constover=符号();constisOver=function(_over){return_over===over;}生成函数rangerange函数接受一个开始和结束参数,返回一个评估函数,运行评估函数并返回一个值,终止时返回终止值。constrange=function(from,to){让我=从;返回函数(){if(i{return++i>=num;});}collectfunctionjoin因为返回的是一个函数,最好用一个join函数来收集所有的值并返回一个数组。constjoin=function(flow){constarray=[];while(true){constdata=flow();如果(isOver(数据)){中断;}大批。推(数据);}返回数组;}测试:constnums=join(take(filter(map(range(0,20),n=>n*10),n=>n%3===0),2));控制台日志(数字);/*输出range1map1range2map2range3map3filter30range4map4range5map5range6map6filter60[30,60]*/一个更优雅的实现使用函数+闭包上面的惰性求值,但还是不够优雅,大部分代码都放在了迭代和评估是否完成的判断上。其实在es6中实现惰性求值还有更好的方法,那就是使用生成器。生成器帮我们解决了迭代,判断流程是否完整,让我们可以专注于逻辑,写出更简洁、易懂、结构清晰的代码。constrange=function*(from,to){for(leti=from;i=number;}returnstop(flow,_filter);}还得上链式调用才算完成了。class_Lazy{constructor(){this.iterator=null;}range(...args){this.iterator=range(...args);归还这个;}map(...args){this.iterator=map(this.iterator,...args);归还这个;}filter(...args){this.iterator=filter(this.iterator,...args);归还这个;}take(...args){this.iterator=take(this.iterator,...args);归还这个;}[Symbol.iterator](){returnthis.iterator;}}functionlazy(){returnnew_Lazy();}***再测试一次:constnums=lazy().range(0,100).map(n=>n*10).filter(n=>n%3===0).take(2);for(letnofnums){console.log('num:\t',n,'\n');}/*输出范围0map0filter0num:0range1map1filter10range2map2filter20range3map3filter30num:30*/好的,你已经完成了。总结这样,我们就完成了最简单的数组惰性求值库。这里简单的实现了惰性求值,需要在项目中加入很多细节。因为代码只有80行,你可以清楚地理解惰性求值的原理,加深你对生成器的理解。***这里是github地址。