Javascript 数组越界:与未定义的比较或长度检查?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6728424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Array Out of Bounds: Comparison with undefined, or length check?
提问by Manav
this seems to be a common javascript idiom:
这似乎是一个常见的 javascript 习语:
function foo (array, index) {
if (typeof array[index] == 'undefined')
alert ('out of bounds baby');
}
as opposed to the more prevalent (in other languages) and conceptually simpler:
与更普遍的(在其他语言中)和概念上更简单的相反:
function foo (array, index) {
if (index >= array.length)
alert ('boo');
}
I understand that the first case will also work for arrays which have 'gaps' in them, but is that a common enough case to warrant the idiom?
我知道第一种情况也适用于其中有“间隙”的数组,但这是一个足够常见的情况来保证成语吗?
The code sample that prompted this question can be seen here. In this case, when using the 'argument' variable inside a function, isn't it sane to assume that it will be a contiguous array?
可以在此处查看提示此问题的代码示例。在这种情况下,当在函数内使用 'argument' 变量时,假设它将是一个连续数组不是很明智吗?
回答by
The only correctway is to check the index vs. the length.
唯一正确的方法是检查索引与长度。
An element may be assigned the value undefined
. It is just sillyto use it for a sentinel here. (There may be other, valid and possibly overlapping, reasons for checking for undefined, but not "for an out of bound check" -- the code in the other question will present arguably wrong results when the value of the given arg is reallyundefined
.)
可以为元素分配值undefined
。在这里用它作为哨兵是愚蠢的。(可能存在其他有效且可能重叠的检查未定义的原因,但不是“越界检查”——当给定 arg 的值真的是undefined
. )
Happy coding.
快乐编码。
回答by Sophie Alpert
You can also write:
你也可以写:
if (index in array) {
which will return true even if array[index]
is set to undefined
.
即使array[index]
设置为,也会返回 true undefined
。
回答by jfriend00
Do not test for undefined. You should use the length of the array. There are cases where it simply does not work to test for undefined because undefined is a legal value for legitimate array entry. Here's a legal JS array:
不要测试未定义。您应该使用数组的长度。在某些情况下,它根本无法测试 undefined,因为 undefined 是合法数组条目的合法值。这是一个合法的 JS 数组:
var legalArray = [4, undefined, "foo"];
And you can access it like this:
您可以像这样访问它:
var legalArray = [4, undefined, "foo"];
var result = "";
for (var i = 0; i < legalArray.length; i++) {
result += legalArray[i] + "<br>";
}
$("#result").html(result);
Generates this output:
生成此输出:
4
undefined
foo
As seen in this jsFiddle: http://jsfiddle.net/jfriend00/J5PPe/
正如在这个 jsFiddle 中看到的:http: //jsfiddle.net/jfriend00/J5PPe/
回答by RobG
It's not common as far as I know, much more common is:
据我所知,这并不常见,更常见的是:
for (var i=0, iLen=array.length; i<iLen; i++) {
// do stuff
}
You should not compare to undefined, since a member of the array may have been assigned a value of undefined
, or may not have been assigned any value.
您不应与 undefined 进行比较,因为数组的成员可能已被分配了 值undefined
,或者可能尚未被分配任何值。
e.g.
例如
var a = [0,,,,];
alert(a.length); // 4 (or 5 in buggy IE);
a[1] === undefined; // true but not out of bounds
The main reason for using a for loop is that array properties may not be returned in numeric order if a for..in loop is used.
使用 for 循环的主要原因是如果使用 for..in 循环,数组属性可能不会按数字顺序返回。
A for..in loop is much more efficient in sparse arrays but the possible out-of-order access must be dealt with if it matters (as must inherited and non-numeric enumerable properties if they should be avoided).
for..in 循环在稀疏数组中效率更高,但如果可能的无序访问很重要,则必须处理它(如果应避免继承和非数字可枚举属性,则必须处理它们)。
回答by cwallenpoole
In that case, the test it to make sure that it does not accidentally add the String "undefined" to the calling String. In the case below, it will actually do just that:
在这种情况下,测试它以确保它不会意外地将字符串“未定义”添加到调用字符串。在下面的情况下,它实际上会做到这一点:
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"
Personally, though, I would probably simply cache the length and then do a numeric comparison.
不过,就我个人而言,我可能会简单地缓存长度,然后进行数字比较。
EDIT
编辑
Side note: his method also avoids a NaN check but forces a strict parallel:
旁注:他的方法也避免了 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")