
本文介绍在不使用 `array.length` 的前提下,安全、可靠地手动计算 javascript 数组长度的多种方式,重点纠正常见的无限循环错误,并推荐简洁现代的实现方案。
你提供的代码陷入无限循环,根本原因在于:变量 i 未初始化(值为 undefined),导致 array[i] 实际等价于 array[undefined],其结果为 undefined;而 'undefined' 是字符串,undefined != 'undefined' 恒为 true,因此条件永远成立。 此外,即使修复了初始化问题,用 array[i] != 'undefined' 判断边界也存在严重缺陷——它无法区分数组中真实存在的 undefined 元素与越界访问返回的 undefined,极易导致提前终止或越界。
✅ 正确的手动计数应基于索引是否存在,而非值是否等于某个字符串。以下是几种推荐方案:
✅ 方案一:for 循环 + in 操作符(兼顾稀疏数组)
let array = [1, 2, 3, 4, 5];
let count = 0;
for (let i in array) {
if (array.hasOwnProperty(i) && !isNaN(i) && i >= 0 && Number.isInteger(Number(i))) {
count++;
}
}
console.log("length of array is " + count); // 5⚠️ 注意:for...in 会遍历所有可枚举属性(包括自定义属性),因此需配合 hasOwnProperty() 和类型校验,适用于需处理稀疏数组的场景,但日常不推荐。
✅ 方案二:经典 for 循环(最直观、高效、通用)
let array = [1, 2, 3, 4, 5];
let count = 0;
for (let i = 0; i < array.length; i++) { // ✅ 利用 length 做边界 —— 但题目要求“不用 length”?
count++;
}
// 若严格禁止使用 length,则改用:
for (let i = 0; array[i] !== undefined || i in array; i++) {
if (i in array) count++; // 确保只计有效索引
}
console.log("length of array is " + count);? 提示:虽然 array[i] !== undefined 仍可能误判(如元素本身就是 undefined),但配合 i in array 可准确识别稀疏数组中的“空位”。
✅ 方案三:forEach(现代、简洁、语义清晰 —— 推荐!)
let array = [1, 2, 3, 4, 5];
let count = 0;
array.forEach(() => count++); // 无需参数,仅计数
console.log("length of array is " + count); // 5
console.log('Native length:', array.length); // 验证结果一致✅ 优势:自动遍历所有存在的数值索引项,天然规避 undefined 元素干扰;代码简短、可读性强、无索引管理负担,是当前最佳实践。
❌ 不推荐的写法(含原问题代码问题总结)
- while (array[i] != 'undefined'):比较类型错误(undefined vs 字符串 'undefined'),且 i 未初始化;
- while (array[i] !== undefined):无法区分 arr[2] = undefined 和 arr[10] 越界;
- for (let i = 0; array[i] != null; i++):null 和 0、false、'' 均为 falsy,同样不可靠。
? 总结:手动计算数组长度本质是统计“连续数值索引从 0 开始的有效项数”。在实际开发中,应优先使用原生 array.length;若出于学习或特殊约束需手动实现,推荐 forEach 方案——它简洁、安全、符合现代 JavaScript 语义,且完全规避索引越界与类型判断陷阱。










