数组越界:与未定义的比较,或长度检查
Array Out of Bounds: Comparison with undefined, or length check?
这似乎是一个常见的javascript习语:
function foo (array, index) {
if (typeof array[index] == 'undefined')
alert ('out of bounds baby');
}
相对于更流行的(在其他语言中)和概念上更简单的
function foo (array, index) {
if (index >= array.length)
alert ('boo');
}
我知道第一种情况也适用于其中有"间隙"的数组,但是这是一种足够常见的情况来保证习语吗?
提示这个问题的代码示例可以在这里看到。在这种情况下,当使用'参数'变量内部的函数,是不是明智的假设,它将是一个连续的数组?
唯一正确的方法是检查索引和长度。
元素可以赋值为undefined
。在这里用它做哨兵实在是太愚蠢了。(检查未定义可能有其他有效且可能重叠的原因,但不是"越界检查"——当给定参数的值确实 undefined
时,另一个问题中的代码将显示有争议的错误结果。)
快乐编码。
你也可以这样写:
if (index in array) {
,即使array[index]
设置为undefined
,也将返回true。
不要测试undefined。您应该使用数组的长度。在某些情况下,测试undefined根本不起作用,因为undefined是合法数组条目的合法值。这是一个合法的JS数组:
var legalArray = [4, undefined, "foo"];
你可以像这样访问它:
var legalArray = [4, undefined, "foo"];
var result = "";
for (var i = 0; i < legalArray.length; i++) {
result += legalArray[i] + "<br>";
}
$("#result").html(result);
生成如下输出:
4
undefined
foo
如下所示:http://jsfiddle.net/jfriend00/J5PPe/
据我所知,这并不常见,更常见的是:
for (var i=0, iLen=array.length; i<iLen; i++) {
// do stuff
}
不应该与undefined进行比较,因为数组的成员可能被赋值为undefined
,也可能没有被赋值。
。
var a = [0,,,,];
alert(a.length); // 4 (or 5 in buggy IE);
a[1] === undefined; // true but not out of bounds
使用for循环的主要原因是,如果使用for..in循环,数组属性可能不会按数字顺序返回。
for..in循环在稀疏数组中效率更高,但如果有必要,必须处理可能的乱序访问(如必须避免继承和非数字可枚举属性)。
在JavaScript中数组可以是稀疏的——它们可以包含"空洞"。例如
const array = new Array(3);
导致array
为三个"孔"。-不是值。因此,尽管
const isInBounds = 0 <= index && index < array.length;
正确识别index
是否在array
的边界内,但不指示array[index]
是否有值。
Object.prototype.hasOwnProperty()
可用于确定index
中是否存在值。还需要注意的是,语言的不同部分在"洞"的存在下会表现得非常不同。
// ESLint: no-prototype-builtins)
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);
// "index -1 is out of bounds"
for (let i = 0; i < subject.length; i += 1) show(subject, i);
// "index 0 holds undefined"
// "index 1 is a hole"
// "index 2 holds 1"
show(subject, 3);
// "index 3 is out of bounds"
const toString = (value) =>
value !== undefined ? value.toString() : 'undefined';
// for..of doesn't skip holes
const byForOf = [];
for (const value of subject) byForOf.push(toString(value));
console.log(`Values found by for..of: ${byForOf.join(', ')}`);
// "Values found by for..of: undefined, undefined, 1"
// .forEach skips holes
const byForEach = [];
subject.forEach((value) => byForEach.push(toString(value)));
console.log(`Values found by .forEach: ${byForEach.join(', ')}`);
// "Values found by .forEach: undefined, 1"
// .reduce skips holes
const reducer = (acc, value) => {
acc.push(toString(value));
return acc;
};
const byReduce = subject.reduce(reducer, []);
console.log(`Values found by .reduce: ${byReduce.join(', ')}`);
// "Values found by .reduce: undefined, 1"
// .map preserves holes
const byMap = subject.map(toString);
console.log(`Values found by .map: ${byMap.join(', ')}`);
// "Values found by .map: undefined, , 1"
在这种情况下,测试它以确保它不会意外地将字符串"undefined"添加到调用字符串中。在下面的例子中,它就会这样做:
var undefd;
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", undefd, "ASP.NET")
// output as "ASP is dead, but {1} is alive! ASP ASP.NET"
就我个人而言,我可能会简单地缓存长度,然后进行数值比较。
编辑
旁注:他的方法也避免了NaN检查,但强制执行严格的并行:
// this will fail unless 0001 is cast to a number, which means the method
// provided will fail.
"{0} is dead, but {1} is alive! {0001} {2}".format("ASP", "ASP.NET")
- 为什么不't Javascript对我的输入值进行了一些重新检查
- 比较从函数和生成的日期对象
- 在单击任何位置时隐藏元素,而不检查每次DOM单击
- 如何使用 node.js 比较两个 json 数组
- 如何检查管道中未定义的项目
- 在angularJS中用字符串比较检查Json对象
- JavaScript 赋值与条件检查中的代码效率和速度比较
- 将数组与 DOM 元素进行比较会检查相同的 ID
- 比较两个“;字符串”;以检查它们是否相等
- 在javascript中检查并比较数组中的数组
- 什么更快?两次比较或一次比较与一次逻辑检查
- 在运行时检查是否有正确的日期类型,以便进行比较
- Do循环检查数组.每次将I与array.length进行比较时
- Jquery比较数据/对象的差异检查
- 我如何检查/比较我的JavaScript代码速度/性能
- 数组越界:与未定义的比较,或长度检查
- PHP将字符串转换为变量,检查其值是否为空,并与其他值进行比较
- 对象比较:检查一个对象是否包含整个其他对象
- 如何使用jquery比较或检查html元素的输入字段类型
- 如何检查哪个日期是第一在比较两个日期在一年中使用php