JavaScript中filter方法内赋值返回值问题及购物车异常分析
关于JavaScript赋值操作返回值与filter/map误用的问题解答
核心疑问解答
product.qty = qty这个赋值操作的返回值就是被赋予的qty值本身。这是JavaScript的语法规则:赋值表达式的结果等于右侧被赋值的内容。
为什么传入0时商品会被移除?
filter方法的逻辑是:回调函数返回值会被转为布尔值,true则保留当前元素,false则丢弃。
- 当传入非0的
qty时,赋值操作返回该非0数值,转为布尔值是true,所以商品被保留,同时qty也被修改成功。 - 当传入
0时,赋值操作返回0,转为布尔值是false,所以这个商品直接被filter过滤掉了。
为什么用map会导致对应位置变成0?
map方法的作用是将每个元素替换为回调函数的返回值。如果直接写product.id === pid ? product.qty = qty : product,匹配到的元素会返回赋值操作的结果(也就是qty),而非原对象。所以当qty=0时,对应位置就变成了数值0,而不是原来的商品对象,不符合需求。
正确的实现方式
修改购物车商品数量的逻辑应该拆分:修改数量用map(推荐用 immutable 方式创建新对象,避免修改原对象),移除数量为0的商品用filter。示例代码如下:
let cart = [{ id: 1, title: "Product 1", qty: 1 }, { id: 2, title: "Product 2", qty: 1 }, ] const changeQty = (pid, qty) => { // 先修改对应商品的数量,再过滤掉数量为0的商品 cart = cart .map(product => product.id === pid ? {...product, qty} : product) .filter(product => product.qty > 0); console.log(cart); } changeQty(1, 0); // 输出 [{id: 2, title: "Product 2", qty: 1}] changeQty(2, 3); // 输出 [{id: 1, title: "Product 1", qty: 1}, {id: 2, title: "Product 2", qty: 3}]
如果需要区分“修改数量为0”和“直接删除”的逻辑,也可以拆分判断:
const changeQty = (pid, qty) => { if (qty === 0) { // 数量为0时直接移除商品 cart = cart.filter(product => product.id !== pid); } else { // 否则修改对应商品的数量 cart = cart.map(product => product.id === pid ? {...product, qty} : product ); } console.log(cart); }
内容的提问来源于stack exchange,提问作者Gnanavel
相关产品推荐
相关产品推荐

