让函数进化

本文同步自我的 GitHub

假定如今有如许一个场景,一个下单页面,须要依据特定的前提去盘算购物车商品的总价,特定的前提包含但不限于选中的商品、是不是挑选折扣、是不是叠加套餐和运费险等。这时刻我们一般须要写一个用来盘算总价的函数getTotalPrice(),但是,函数的参数是不肯定的,同时函数内的逻辑也会依据参数的差别而有所变化,最简朴的要领是在函数内部对参数举行推断:

假如参数离开传入,那末函数的伪代码能够写成如许:

function getTotalPrice(selectedGoods, isDiscounted, pacakge) {
    var totalPrice = 0;
    if (selectedGoods) {
        totalPrice = ...;
        if (isDiscounted) {
            // 盘算折扣
            if (package) {...}
        } else if (pacakge) {...}
        return totalPrice;
    } else {
        return 0;
    }
}

有的人能够以为将参数离开传入函数看起来比较乱,会习习用一个参数对象包裹一下,在函数内部再对这个对象举行剖析。看起来确切有肯定的革新,但我以为并没有什么本质上的区分。

如今愿望能够做到针对差别参数的状况,在函数内部只誊写针对特定个数参数的逻辑,不去写杂乱无章的if-else语句或是参数对象的剖析逻辑。同时,这些函数共用一个函数名,而且该逻辑可扩大,即能够随时依据须要,增添函数。

经由过程对需求的剖析,应当会有如许的一个东西函数:

var methods = {};

addFunction(methods, 'getTotalPrice', function(selectedGoods) {...});
addFunction(methods, 'getTotalPrice', function(selectedGoods, isDiscounted) {...});
addFunction(methods, 'getTotalPrice', function(selectedGoods, isDiscounted, pacakge) {...});

如许,在增添每一个函数的时刻,只须要写针对特定参数的逻辑,挪用getTotalPrice的时刻,自动依据参数长度现实挪用差别的函数。

很轻易想到要对差别的函数举行缓存,同时为了公用同一个函数名,缓存的函数须要匿名,进而联想到闭包能够保留局部变量的援用的特征,以下是addFunction的完成:

function addFunction(object, funcName, fn) {
    var oldFunc = object[funcName];
    object[funcName] = function() {
        return (fn.length === arguments.length ? fn : oldFunc).apply(this, arguments);
    }
}

addFunction要领的作用域中,保留了原要领的援用,经由过程对参数长度的比较肯定终究实行哪一个匿名函数,要注意的是一个函数的length属性示意改函数接收的形参数目,而arguments.length示意现实传入的参数数目。匿名函数接见oldFuncfn则是典范的闭包的运用,并没有把函数存储在任何典范的数据结构中。

addFunction(methods, 'getTotalPrice', function(total) {
    console.log(total);
});
addFunction(methods, 'getTotalPrice', function(total, discount) {
    console.log(total * discount);
});

methods.getTotalPrice(20); // 输出20
methods.getTotalPrice(20, 0.8); // 输出16

要注意的是,这类体式格局只能针对差别数目的参数,不能推断参数的称号或范例,假如要推断的话,势必会捐躯addFunction要领的通用性。别的,每增添一个函数,就会增添一层嵌套,挪用深度过深的话机能开支也会比较大,运用的时刻要举行衡量。

    原文作者:classicemi
    原文地址: https://segmentfault.com/a/1190000003958809
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞