JavaScript生成数字数组:4种方法搞定0到10

摘要:在JavaScript开发中,经常需要生成连续的数字数组。比如要生成0到10的数组,有好几种方法可以实现。今天介绍4种常用的方法,从最简单到最灵活,你可以根据需求选择。

在JavaScript开发中,经常需要生成连续的数字数组。比如要生成0到10的数组,有好几种方法可以实现。今天介绍4种常用的方法,从最简单到最灵活,你可以根据需求选择。


方法一:Array.from(最推荐)

这是现在最常用的方法,一行代码就能搞定:

const arr = Array.from({ length: 11 }, (_, i) => i);
console.log(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

工作原理

  1. { length: 11 } 创建一个类似数组的对象,有11个位置

  2. Array.from() 把这个类数组转成真正的数组

  3. 第二个参数是处理函数,i 是当前位置的索引

  4. 函数返回索引值,就得到了0到10的数字

为什么推荐?

  • 代码简洁,一眼就能看懂

  • 现代JavaScript的标准写法

  • 支持所有现代浏览器

生成其他范围的数组

// 生成 0~20
const arr1 = Array.from({ length: 21 }, (_, i) => i);

// 生成 1~10
const arr2 = Array.from({ length: 10 }, (_, i) => i + 1);

// 生成偶数 0, 2, 4, ..., 10
const arr3 = Array.from({ length: 6 }, (_, i) => i * 2);


方法二:扩展运算符 + keys()

这个方法也很简洁,利用了数组的迭代器:

const arr = [...Array(11).keys()];
console.log(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

逐步解析

  1. Array(11) 创建一个长度11的空数组

  2. .keys() 返回数组索引的迭代器(0到10)

  3. ... 扩展运算符把迭代器转成真正的数组

适用场景

  • 需要生成连续索引时

  • 代码要求极简风格

  • 只需要0开始的序列

限制

  • 只能从0开始

  • 不能直接生成其他起始值的序列


方法三:for循环(最传统)

虽然代码多一点,但最基础最容易理解:

const arr = [];
for (let i = 0; i <= 10; i++) {
    arr.push(i);
}
console.log(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

变体:while循环

const arr = [];
let i = 0;
while (i <= 10) {
    arr.push(i);
    i++;
}

什么时候用for循环?

  1. 初学者学习时:逻辑最清晰

  2. 需要复杂逻辑时:可以在循环里添加条件判断

  3. 性能关键场景:有时比高阶函数略快

  4. 旧项目维护:兼容性最好

生成复杂序列的例子

// 生成平方数数组
const squares = [];
for (let i = 0; i <= 10; i++) {
    squares.push(i * i);
}
// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

// 跳过某些数字
const filtered = [];
for (let i = 0; i <= 10; i++) {
    if (i % 2 === 0) {  // 只要偶数
        filtered.push(i);
    }
}
// [0, 2, 4, 6, 8, 10]


方法四:封装成通用函数

如果你经常需要生成不同范围的数组,可以封装一个函数:

/**
 * 生成连续数字数组
 * @param {number} start - 起始数字
 * @param {number} end - 结束数字
 * @param {number} step - 步长(默认1)
 * @returns {number[]} 生成的数组
 */
function range(start, end, step = 1) {
    const result = [];
    for (let i = start; i <= end; i += step) {
        result.push(i);
    }
    return result;
}

// 使用例子
const arr1 = range(0, 10);     // [0, 1, 2, ..., 10]
const arr2 = range(1, 10);     // [1, 2, 3, ..., 10]
const arr3 = range(0, 10, 2);  // [0, 2, 4, 6, 8, 10]
const arr4 = range(10, 0, -1); // [10, 9, 8, ..., 0]

更完善的版本

function range(start, end, step = 1) {
    // 参数验证
    if (typeof start !== 'number' || typeof end !== 'number') {
        throw new Error('参数必须是数字');
    }
    
    if (step === 0) {
        throw new Error('步长不能为0');
    }
    
    const result = [];
    
    // 处理递减序列
    if (start > end && step > 0) {
        step = -step;
    }
    
    // 生成数组
    if (step > 0) {
        for (let i = start; i <= end; i += step) {
            result.push(i);
        }
    } else {
        for (let i = start; i >= end; i += step) {
            result.push(i);
        }
    }
    
    return result;
}


性能比较

测试代码

// 测试不同方法的性能
const testSize = 1000000; // 生成100万个数字的数组

console.time('Array.from');
const arr1 = Array.from({ length: testSize }, (_, i) => i);
console.timeEnd('Array.from');

console.time('扩展运算符');
const arr2 = [...Array(testSize).keys()];
console.timeEnd('扩展运算符');

console.time('for循环');
const arr3 = [];
for (let i = 0; i < testSize; i++) {
    arr3.push(i);
}
console.timeEnd('for循环');

console.time('map方法');
const arr4 = Array(testSize).fill(0).map((_, i) => i);
console.timeEnd('map方法');

结果分析(仅供参考):

  • for循环:通常最快,特别是大数据量时

  • Array.from:现代浏览器中表现很好

  • 扩展运算符:简洁但可能稍慢

  • map方法:最慢,不推荐

实际建议:

  • 小数组(<1000个元素):用哪个都行,差别很小

  • 大数组:优先用for循环或Array.from

  • 考虑可读性比微小性能差异更重要


常见需求解决方案

1. 生成1到10的数组

// 方法1
const arr1 = Array.from({ length: 10 }, (_, i) => i + 1);

// 方法2
const arr2 = [...Array(10).keys()].map(i => i + 1);

// 方法3
const arr3 = [];
for (let i = 1; i <= 10; i++) {
    arr3.push(i);
}

2. 生成10到0的递减数组

// 方法1
const arr1 = Array.from({ length: 11 }, (_, i) => 10 - i);

// 方法2
const arr2 = [...Array(11).keys()].map(i => 10 - i);

// 方法3
const arr3 = [];
for (let i = 10; i >= 0; i--) {
    arr3.push(i);
}

3. 生成特定规律的数组

// 生成0到100的偶数
const evens = Array.from({ length: 51 }, (_, i) => i * 2);

// 生成1到10的平方数
const squares = Array.from({ length: 10 }, (_, i) => (i + 1) ** 2);

// 生成斐波那契数列前10项
const fib = [0, 1];
for (let i = 2; i < 10; i++) {
    fib.push(fib[i - 1] + fib[i - 2]);
}


实际应用场景

场景1:分页组件

// 生成页码数组
function generatePageNumbers(currentPage, totalPages) {
    const start = Math.max(1, currentPage - 2);
    const end = Math.min(totalPages, currentPage + 2);
    
    return Array.from(
        { length: end - start + 1 },
        (_, i) => start + i
    );
}

// 假设总共10页,当前在第5页
const pages = generatePageNumbers(5, 10);
// [3, 4, 5, 6, 7]

场景2:数据可视化

// 生成x轴刻度
function generateXAxis(start, end, interval) {
    const length = Math.floor((end - start) / interval) + 1;
    return Array.from({ length }, (_, i) => start + i * interval);
}

// 生成0到100,间隔10的刻度
const ticks = generateXAxis(0, 100, 10);
// [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

场景3:测试数据

// 生成测试用户数据
const testUsers = Array.from({ length: 10 }, (_, i) => ({
    id: i + 1,
    name: `用户${i + 1}`,
    age: Math.floor(Math.random() * 50) + 20,
    email: `user${i + 1}@example.com`
}));


最佳实践建议

1. 根据项目选择

  • 新项目:优先用Array.from,代码简洁

  • 旧项目:保持现有代码风格一致

  • 库/框架开发:考虑兼容性,可以用for循环

2. 代码可读性

给复杂操作加注释:

// 生成0到10的数组,用于遍历操作
const indices = Array.from({ length: 11 }, (_, index) => index);

3. 错误处理

function safeRange(start, end, step = 1) {
    if (typeof start !== 'number' || typeof end !== 'number') {
        console.warn('range函数需要数字参数');
        return [];
    }
    
    if (step === 0) {
        console.warn('步长不能为0');
        return [];
    }
    
    try {
        const length = Math.floor((end - start) / step) + 1;
        return Array.from({ length }, (_, i) => start + i * step);
    } catch (error) {
        console.error('生成数组时出错:', error);
        return [];
    }
}

4. 性能优化

  • 小数组不必过度优化

  • 大数组考虑预分配大小(如果需要用for循环)


总结

生成0到10的数组,有几种常用方法:

  1. 最推荐:Array.from({ length: 11 }, (_, i) => i)

    • 简洁明了

    • 现代JavaScript标准

    • 功能灵活

  2. 简洁选择:[...Array(11).keys()]

    • 代码更短

    • 适合只需要0开始的情况

  3. 基础方法:for循环

    • 最好理解

    • 兼容性最好

    • 适合复杂逻辑

  4. 通用方案:封装range函数

    • 适合频繁使用

    • 功能最完整

    • 便于维护

选择哪种方法,主要看你的具体需求。日常开发中,Array.from基本能满足大部分场景。记住,写代码不仅要能用,还要让别人(包括未来的你)能看懂。选择合适的方法,写出清晰易读的代码最重要。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_13279