编程概念

  • closure 闭包:一个子函数,引用父函数的变量,当父函数执行完成,子函数依然能访问这些变量。

  • argument drilling: 指的是在开发的时候,函数在调用链的时候,有很多参数要传递,比如A调用B,传了一些参数,B调用C的时候,又要传这个参数。有几个办法可以解决这个问题

    • 对象传参:将相关参数封装到一个对象里

    • 依赖注入:用依赖注入来管理和传递函数所需要的依赖项

    • 使用全局变量虽然也能解决,但可能会引入其他问题,比如命名冲突,可维护性差,难以测试等,不推荐使用。

    • 使用 closure 闭包在一定程度上也能解决参数的问题,一个示例如下

      • 比如一个计算折扣的程序,原始写法如下

async function getUserDiscounts() {
    return {
        P001: 5,
        P002: 10
    }
}

async function getCategoryDiscounts() {
    return {
        electronics: 15,
        clothing: 5
    }
}

function proceeProducts(products, userDiscounts, categoryDiscounts) {
    return products
    .map((product) => {
        const userDiscount = userDiscounts[product.id] || 0;
        const categoryDiscount = categoryDiscounts[product.category] || 0;
        const totalDiscount = userDiscount + categoryDiscount;
        const finalPrice = product.price - product.price * (totalDiscount / 100);
        return {
            ...product, 
            finalPrice: finalPrice.toFixed(2)
        };
    })
    .filter((product) => product.finalPrice <= 80)
    .map((product) => product.id)
}

async function main() {
    const products = [
        {id: "P001", category: "electronics", price: 100},
        {id: "P002", category: "clothing", price: 50},
        {id: "P003", category: "electronics", price: 100},
        {id: "P004", category: "clothing", price: 80}
    ]
    const userDiscounts = await getUserDiscounts();
    const categoryDiscounts = await getCategoryDiscounts();

    const processedProducts = proceeProducts(
        products,
        userDiscounts,
        categoryDiscounts
    );

    console.log(
        processedProducts.reduce(
            (obj, key) => {obj[key] = key; return obj;}, {}
        )
    );
}

main()

此时折扣的逻辑在多个地方都会用到,此时我们可以创建一个createDiscountCalculator的函数专门计算折扣,这个函数需要接收 userDiscounts 和 categoryDiscounts 作为输入,在专门处理某一个商品时,然后再通过这个 discountCalculator 查一下商品折扣,具体改法是:

下面是一个python 通过闭包的一个实现

Last updated