Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 数组越界:与未定义的比较,还是长度检查?_Javascript_Arrays - Fatal编程技术网

Javascript 数组越界:与未定义的比较,还是长度检查?

Javascript 数组越界:与未定义的比较,还是长度检查?,javascript,arrays,Javascript,Arrays,这似乎是一个常见的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'

这似乎是一个常见的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');
}
我知道第一种情况也适用于有“间隙”的数组,但这种情况是否足够普遍,足以证明这种习惯用法的正确性

可以看到提示此问题的代码示例。在这种情况下,当在函数中使用'argument'变量时,假设它将是一个连续数组,这难道不明智吗?

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

可以为元素指定值
未定义
。在这里当哨兵真是太傻了。(检查未定义可能有其他有效且可能重叠的原因,但不是“检查越界”--当给定arg的值实际上是
未定义时,另一个问题中的代码可能会给出错误的结果)


快乐编码。

据我所知,这并不常见,更常见的是:

for (var i=0, iLen=array.length; i<iLen; i++) {
  // do stuff
}
使用for循环的主要原因是,如果使用for..in循环,数组属性可能不会以数字顺序返回


for..in循环在稀疏数组中效率更高,但如果有问题,则必须处理可能的无序访问(如果应该避免,则必须处理继承的和非数字的可枚举属性)。

在这种情况下,测试它以确保它不会意外地将字符串“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")

不要测试未定义的。您应该使用数组的长度。在某些情况下,测试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);
如本JSFIDLE所示:

您还可以编写:

if (index in array) {

即使
array[index]
设置为
undefined

,它也将返回true。在JavaScript中,数组可以是稀疏的,它们可以包含“洞”。比如说

const数组=新数组(3);
结果是一个由三个“孔”组成的
数组
,而不是值。那么一会儿

const isInBounds=0 index | | index>=array.length
? `索引${index}超出范围`
: !调用(数组、索引)
? `索引${index}是一个洞`
:`index${index}包含${array[index]}`;
控制台日志(msg);
}
const subject=[未定义,1];
显示(主题-1);
//“索引-1超出范围”
对于(设i=0;i
值!==未定义?value.toString():“未定义”;
//因为…当然不会跳过洞
常数byForOf=[];
通过forof.push(toString(value)),for(主体的常量值);
log(`value-find by for..of:${byForOf.join(',')}`);
//为…找到的值:未定义,未定义,1
//.forEach跳洞
常量byForEach=[];
subject.forEach((值)=>byForEach.push(toString(值));
log(`valuesfoundby.forEach:${byForEach.join(',')}`);
//.forEach找到的值:未定义,1
//.减少跳板孔
常数减速机=(acc,值)=>{
acc.push(toString(值));
返回acc;
};
constbyreduce=subject.reduce(reducer,[]);
log(`valuesfoundby.reduce:${byReduce.join(',')}`);
//由找到的值。减少:未定义,1
//.地图保留洞
constbymap=subject.map(toString);
log(`valuesfoundby.map:${byMap.join(',')}`);
//由找到的值。映射:未定义,1

我认为您误解了链接的代码。replace函数可以随机访问arguments数组(一个类似于
“{1}{3}{5}{2}”
的字符串就是一个例子),这可能会对传递它的参数产生有趣的影响。我的观点是,这里的检查不是检查数组的边界,而是检查是否存在,并在命名属性未定义时提供回退。99%的情况下,您希望对照
length
属性进行检查,链接的代码是少数不检查的情况之一。此外,测试应该是
if(index
,因为长度总是比上一个索引多一个,并且
array[array.length]
总是未定义。作为练习,尝试执行以下代码:
var arr=[];arr[5]=2。执行第一个循环,您将立即在索引0处得到一条越界消息,但是arr.length将正确地告诉您,
arr
有6个元素。这并不总是有效的——尽管我相信它在
参数
的情况下总是有效的,因为JavaScript中的数组是“稀疏的”。这就是为什么(数组中的v){…}
有时会出现问题的原因。(有一个
未定义的
值和一个未设置的索引是有区别的,这两个值都适用于
和未设置的索引。例如,考虑<代码> var a= [];a[1]=“foo”;a
中的0将导致false。
a
中的数组有自己的属性“1”和“length”,但它没有名为“0”的属性。
4
undefined
foo
if (index in array) {