数组超出界限:与未定义或长度检查的比较?

时间:2022-07-02 21:42:38

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'变量时,假设它是一个连续的数组是不是很明智?

5 个解决方案

#1


20  

The only correct way is to check the index vs. the length.

唯一正确的方法是检查索引与长度。

An element may be assigned the value undefined. It is just silly to 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 really undefined.)

可以为元素分配值undefined。把它用作这里的哨兵真是太傻了。 (可能存在检查未定义的其他,有效且可能重叠的原因,但不是“对于越界检查” - 当给定arg的值确实未定义时,另一个问题中的代码将呈现可能错误的结果。)

Happy coding.

快乐的编码。

#2


15  

You can also write:

你也可以这样写:

if ( index in array ) {

which will return true even if array[index] is set to undefined.

即使array [index]设置为undefined,它也会返回true。

#3


0  

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循环在稀疏数组中效率要高得多,但是如果重要的话,必须处理可能的无序访问(如果应该避免,则必须继承和非数字可枚举属性)。

#4


0  

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/

#5


0  

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:

在这种情况下,测试它以确保它不会意外地将字符串“undefined”添加到调用String。在下面的例子中,它实际上会这样做:

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")

#1


20  

The only correct way is to check the index vs. the length.

唯一正确的方法是检查索引与长度。

An element may be assigned the value undefined. It is just silly to 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 really undefined.)

可以为元素分配值undefined。把它用作这里的哨兵真是太傻了。 (可能存在检查未定义的其他,有效且可能重叠的原因,但不是“对于越界检查” - 当给定arg的值确实未定义时,另一个问题中的代码将呈现可能错误的结果。)

Happy coding.

快乐的编码。

#2


15  

You can also write:

你也可以这样写:

if ( index in array ) {

which will return true even if array[index] is set to undefined.

即使array [index]设置为undefined,它也会返回true。

#3


0  

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循环在稀疏数组中效率要高得多,但是如果重要的话,必须处理可能的无序访问(如果应该避免,则必须继承和非数字可枚举属性)。

#4


0  

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/

#5


0  

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:

在这种情况下,测试它以确保它不会意外地将字符串“undefined”添加到调用String。在下面的例子中,它实际上会这样做:

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")