了解 JavaScript 中的范围函数

Understanding a range function in JavaScript

所以,我是编程新手,在这里遇到了一些麻烦。看,我想写一个小范围的函数,比如 range(a,b),它会 return 一个包含 a 和 b 之间所有数字的数组。所以我用谷歌搜索并找到了这个:

const range = (min, max) => [...Array(max - min + 1).keys()].map(i => i + min);

这工作得很好,但我在理解它时遇到了一些麻烦,尤其是 .keys() 部分。我以为 .keys() 是一个对象函数,它将 return 对象的 key/value 对的键,但在我看来,它已被用在数组中。

我哪里理解错了?

感谢您的帮助!

数组有 keys as well and returns an iterator for returning keys. This requires a spreading into an array or use a function which takes iterables 和 returns 个数组。

为此目的制作了 Array.from - 这也具有映射功能。

您可以直接将 Array.from 与具有 length 属性 和映射函数的对象一起使用,而不是构建多个数组。

const range = (min, max) => Array.from(
        { length:  max - min + 1 },
        (_, i) => i + min
    );

console.log(...range(7, 9));

数组也有一个 keys 方法,它是这个 range 函数正常工作的核心。

工作原理如下:

  1. 它创建一个适当长度 (Array(max - min + 1)) 的空 (sparse) 数组。
  2. 它为该数组的有效索引 (.keys()) 获取 iterator。数组中的有效索引是数组长度减一的数字 0。 (从技术上讲,在规范术语中,数组的索引是字符串 属性 名称,如 "0""1" 等,但是 keys 迭代器 return 的数字因为我们通常使用数字来索引数组,这是提供更有用的价值。)
  3. spreads 将迭代器中的元素输出到数组 ([...]) 中。
  4. 它通过映射来自 #3 的数组中的每个值创建一个新数组,并向它们添加 min 值 (.map(i => i + min))。

请注意,这会创建多个中间数组和其他对象。这不太重要,但可以更有效地完成。例如,将 Array.from 作为 ,甚至只是一个简单的循环:

const range = (min, max) => {
    const result = [];
    for (let n = min; n < max; ++n) {
        result.push(n); // Or: `result[result.length] = n;` if you want to
                        // avoid the function call
    }
    return result;
};

const range = (min, max) => {
    const result = [];
    for (let n = min; n < max; ++n) {
        result.push(n);
    }
    return result;
};
console.log(range(5, 10));

不过,这看起来并不那么酷。 :-D

但是,我可能根本不会有 range return 数组,除非我确定那是最终产品我总是需要。相反,我会让它 return 一个迭代器:

const range = function*(min, max) {
    for (let n = min; n < max; ++n) {
        yield n;
    }
};
        
for (const value of range(0, 10)) {
    console.log(value);
}
.as-console-wrapper {
    max-height: 100% !important;
}

如果你需要一个数组,你总是可以把它分散到一个数组中(或与 Array.from 一起使用)。