在JavaScript中,数组可以是稀疏的 - 它们可以包含“空洞”。例如:
const array = new Array(3);
结果是一个包含三个“空洞”(而非值)的数组
。因此,
const isInBounds = 0 <= index && index < array.length;
正确判断index
是否在array
的范围内,但并不表示array[index]
上是否有值。
可以使用Object.prototype.hasOwnProperty()
来确定index
上是否存在值。需要注意的是,语言的不同部分在存在"空洞"时可能会有不同的行为。
const hasOwnProperty = Object.prototype.hasOwnProperty;
function show(array, index) {
const msg =
0 > index || index >= array.length
? `index ${index} is out of bounds`
: !hasOwnProperty.call(array, index)
? `index ${index} is a hole`
: `index ${index} holds ${array[index]}`;
console.log(msg);
}
const subject = [undefined, , 1];
show(subject, -1);
for (let i = 0; i < subject.length; i += 1) show(subject, i);
show(subject, 3);
const toString = (value) =>
value !== undefined ? value.toString() : 'undefined';
const byForOf = [];
for (const value of subject) byForOf.push(toString(value));
console.log(`Values found by for..of: ${byForOf.join(', ')}`);
const byForEach = [];
subject.forEach((value) => byForEach.push(toString(value)));
console.log(`Values found by .forEach: ${byForEach.join(', ')}`);
const reducer = (acc, value) => {
acc.push(toString(value));
return acc;
};
const byReduce = subject.reduce(reducer, []);
console.log(`Values found by .reduce: ${byReduce.join(', ')}`);
const byMap = subject.map(toString);
console.log(`Values found by .map: ${byMap.join(', ')}`);
"{1} {3} {5} {2}"
),这可能会对传递给它的参数产生有趣的影响。我的观点是,那里的检查不是为了检查数组的边界,而是为了检查存在性并在未定义命名属性时提供回退。99%的情况下,您要检查length属性,链接的代码是少数几次不需要检查的情况之一。 - Nick Husherif (index < array.length)
,因为长度始终比最后一个索引多一个,并且array[array.length]
总是未定义的。 - RobGvar arr = []; arr[5] = 2;
。在执行第一个循环时,您将立即收到索引0的越界消息,但是arr.length将正确告诉您arr
有6个元素。 - c1moore