编程概念
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 查一下商品折扣,具体改法是:
async function getUserDiscounts() {
return {
P001: 5,
P002: 10
}
}
async function getCategoryDiscounts() {
return {
electronics: 15,
clothing: 5
}
}
function createDiscountCalculator(userDiscounts, categoryDiscounts) {
return function (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 finalPrice.toFixed(2);
}
}
function proceeProducts(products, discountCalculator) {
return products
.map((product) => {
const finalPrice = discountCalculator(product);
return {
...product,
finalPrice: finalPrice
};
})
.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 discountCalculator = createDiscountCalculator(
userDiscounts,
categoryDiscounts
);
const processedProducts = proceeProducts(
products,
discountCalculator
);
console.log(
processedProducts
);
console.log(
processedProducts.reduce(
(obj, key) => {obj[key] = key; return obj;}, {}
)
);
}
main()
下面是一个python 通过闭包的一个实现
from decimal import Decimal, getcontext
def user_discount():
return {
"P001": 5,
"P002": 10
}
def category_discount():
return {
"electronics": 15,
"clothing": 5
}
def discount_calculator(user_discount, category_discount):
def discount(product):
user_discount_percentage = user_discount.get(product["id"], 0)
category_discount_percentage = category_discount.get(product["category"], 0)
discount_percentage = user_discount_percentage + category_discount_percentage
discount_amount = product["price"] * Decimal(discount_percentage / 100)
discounted_price = product["price"] - discount_amount
return discounted_price
return discount
def proceed_products(products, discount_calculator):
discounted_product = [{**product, 'finalPrice': discount_calculator(product)} for product in products]
filtered_products = [
product["id"] for product in discounted_product if product['finalPrice'] < 80
]
return filtered_products
if __name__ == '__main__':
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
}
]
user_discount = user_discount()
category_discount = category_discount()
discount_calculator = discount_calculator(user_discount, category_discount)
discount_products = proceed_products(products, discount_calculator)
print(discount_products)
最后更新于