在数组循环中执行的判断,执行结果异常

阅读次数 38
  const dataSource = [
    {
      status: 'active'
    },
    {
      status: 'resolved'
    }
  ].map(i => i);

  console.log(dataSource.length); // 1
  const filterData = dataSource.filter(item => {
    console.log(item.status); // 2
    console.log(item.status === 'active'); // 3
    return item.status === 'active';
  });
  console.log(filterData.length); // 4

如上的代码执行结果预期输出顺序是'1 -> 2 -> 3 -> 4',但实际执行时却是'1 -> 2 -> 4 -> 3',判断是最后才执行的,这导致filter方法失效,无法达到判断筛选的目的

1 Answers

实际上,代码的执行逻辑并没有错误,输出顺序也并非 "1 -> 2 -> 4 -> 3"。在 JavaScript 中,数组的 .filter() 方法是立即对数组中的每个元素执行提供的函数,并根据返回值(布尔值)决定该元素是否包含在新数组中。但是,对于 console.log 的打印顺序,并不是按照 .filter() 内部判断的顺序进行的。

这段代码的实际执行流程如下:

首先,console.log(dataSource.length); // 1 输出 dataSource 数组的长度。 然后,.filter() 方法开始遍历dataSource数组: 对于第一个对象 { status: 'active' }: 执行 console.log(item.status); // 2,输出 'active'。
执行 console.log(item.status === 'active'); // 3,输出 true。
因为条件 item.status === 'active' 为真,所以将此对象放入新的过滤数组。
对于第二个对象 { status: 'resolved' }:
同样会执行两次 console.log,但由于问题描述中没有展示这两个输出结果,我们可以推断它们分别是 'resolved' 和 false。
由于条件 item.status === 'active' 为假,所以不会将此对象放入新的过滤数组。
最后,console.log(filterData.length); // 4 输出过滤后的数组长度,这里应该是 1 而不是 4,因为过滤后只剩下一个状态为 'active' 的对象。
因此,实际的输出可能是这样的:

1 'active' true 1
需要注意的是,虽然 console.log(item.status === 'active'); // 3 的输出可能在 console.log(filterData.length); // 4 之后(取决于 console 的异步处理机制),但这并不会影响 .filter() 方法的正确执行和筛选结果。