JS数组方法详解

102 阅读3分钟

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 = [

    { id1name"宫保鸡丁"count2 },

    { id2name"麻婆豆腐"count1 },

    { id3name"米饭"count3 }

]

// 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 = [{ id1count1 }];

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++; // 这样修改不会影响原数组

在购物车场景中,使用引用是正确的做法,因为要修改原始购物车中的数量。