除-1外标记number类型无效值:应选用Infinity还是NaN?
首先你当前的缓存逻辑不能直接用NaN作为初始标记,你写的foo === t判断在foo为NaN时永远不成立,哪怕新获取的t也是NaN,因为NaN === NaN的执行结果恒为false,会导致缓存永远命中失败,每次都重新执行昂贵的计算逻辑。
两种标记值的优劣&缺陷
Infinity
优势:Infinity === Infinity判断直接成立,你原有全等判断逻辑不需要做任何修改,运行时无额外开销,完全满足你不修改变量类型的要求。
需规避的缺陷:必须先确认你的业务逻辑中getFoo()返回的合法数值范围不会包含正负Infinity,避免合法业务值和失效标记撞值,导致缓存误命中。如果业务不会出现除以0、超大数溢出等生成Infinity的场景,优先选这个方案。NaN
优势:语义上更贴合“无效值”的含义,写法更短。
需规避的缺陷:必须修改原有全等判断逻辑,新增Number.isNaN()分支判断,否则缓存判断完全失效;同时需要确认业务中不会返回合法的NaN,否则同样会出现标记和业务值撞值的问题。
适配CoffeeScript场景的修改方案
方案1:业务无Infinity合法值,直接替换标记为Infinity
原有逻辑几乎不需要改动,仅修改初始值即可:
someCachedGetter: do -> foo = Infinity cache = null -> t = getFoo() if foo is t return cache foo = t cache = expensiveOperation()
方案2:业务无NaN合法值,保留NaN标记修改判断逻辑
新增NaN校验分支即可:
someCachedGetter: do -> foo = NaN cache = null -> t = getFoo() if (Number.isNaN(foo) and Number.isNaN(t)) or foo is t return cache foo = t cache = expensiveOperation()
内容的提问来源于stack exchange,提问作者n-smits
相关产品推荐
相关产品推荐

