Arr.filter()
currentDishes() {
const categoryId = this.categories[this.currentCategory].id
return this.dishes.filter(dish => dish.categoryId === categoryId)
},
return this.dishes.filter(dish => dish.categoryId === categoryId)
-
this.dishes是组件中存储的所有菜品数组数据 -
.filter()是JavaScript数组方法,它会创建一个新数组,包含所有通过测试条件的元素 -
dish => dish.categoryId === categoryId是一个箭头函数,作为filter的测试条件: -
dish是filter遍历时的每个菜品对象 -
dish.categoryId获取当前菜品的分类ID -
=== categoryId判断是否等于当前选中的分类ID -
如果相等返回 true,这个菜品会被保留在新数组中
-
如果不相等返回 false,这个菜品会被过滤掉
-
categoryId来自this.categories[this.currentCategory].id,是当前选中分类的ID
所以这段代码的作用是:
-
遍历所有菜品
-
只保留属于当前选中分类的菜品
-
返回筛选后的菜品数组
例如:当用户点击"热菜"分类(categoryId = 1)时,这段代码会返回所有 categoryId 为 1 的菜品。
Arr.reduce()
// 购物车总数量
totalCount() {
return this.cartList.reduce((total, item) => total + item.count, 0)
},
这是一个计算购物车总数量的代码,让我们逐个部分分解: this.cartList - 这是购物车数组,包含了所有已选择的菜品,每个菜品对象都有 count 属性表示该菜品的数量
-
.reduce()- 这是一个数组方法,用于将数组中的所有元素归纳为一个单一的值。它接受两个参数: -
第一个参数是一个回调函数
(total, item) => total + item.count -
第二个参数是初始值 0
-
工作流程:
-
从初始值 0 开始
-
对数组中的每个元素执行回调函数
-
total 是累加器,保存着累加的结果
-
item 是当前正在处理的购物车项目
-
item.count 是当前菜品的数量
-
每次迭代都将当前菜品的数量加到总数上
举个例子:
// 假设购物车数据如下:
cartList = [
{ id: 1, name: "宫保鸡丁", count: 2 },
{ id: 2, name: "麻婆豆腐", count: 1 },
{ id: 3, name: "米饭", count: 3 }
]
// reduce 的执行过程:
// 第一次:total(0) + item.count(2) = 2
// 第二次:total(2) + item.count(1) = 3
// 第三次:total(3) + item.count(3) = 6
// 最终返回 6,表示购物车中总共有 6 件商品
这是一种简洁高效的计算总数的方法,比用循环遍历要更加优雅。
Arr.find()
查找数组元素的方法
const cartItem = this.cartList.find(item => item.id === dish.id)
if (cartItem) {
if (cartItem.count >= dish.stock) {
uni.showToast({
title: '库存不足',
icon: 'none'
})
return
}
cartItem.count++
} else {
this.cartList.push({
id: dish.id,
name: dish.name,
price: dish.price,
count: 1
})
}
},
JavaScript 中对象是通过引用传递的(pass by reference)而不是值传递(pass by value)。让我解释一下这个过程:1. 当执行 this.cartList.find() 时,它返回的 cartItem 不是数组中元素的副本,而是直接指向数组中那个对象的引用(内存地址)
所以当你修改 cartItem.count 时,你实际上是在修改原始对象,因为 cartItem 和 cartList 中的对象指向同一个内存位置
这里是一个简化的例子来说明这个概念:
// 示例1:对象引用
const cart = [{ id: 1, count: 1 }];
const item = cart.find(i => i.id === 1);
item.count++; // cart[0].count 也会变成 2
// 示例2:原始类型的对比
let a = 1;
let b = a;
b++; // a 仍然是 1,因为原始类型是值传递
如果你想要创建一个独立的副本(这样修改就不会影响原数组),你需要进行深拷贝:
// 使用深拷贝
const cartItem = JSON.parse(JSON.stringify(
this.cartList.find(item => item.id === dish.id)
));
cartItem.count++; // 这样修改不会影响原数组
在购物车场景中,使用引用是正确的做法,因为要修改原始购物车中的数量。