检查数组中未定义元素的最佳方法

Best way to check undefined element in an array

我有一个将整数链接到对象的数组:

var array = [];
array[3] = new Something();
array[42] = new OtherSomething();
array[84] = new SomethingAgain();

我想检查某个字段是否存在于数组中,如果存在则使用它。

var field = array[row];

如果数组不包含索引为 row 的任何字段,则 field 将设置为 undefined

我的问题是:检查其存在的最佳方法是什么:

if (field !== undefined) { /* Do stuff with field */ }

并且:

if (field) { /* Do stuff with field */ }

第二个解决方案更短,因此执行起来会更快,因为 JavaScript 是一种解释型脚本语言。但另一方面,它可能会检查 field 的布尔值,或类似的东西...

你对此有何看法?

您创建的数组称为稀疏数组。您可以在 this answer.

中阅读更多相关信息

支票

if (field !== undefined)
如果存储在数组本身中的实际值是 undefined

可能无济于事。还有这张支票

if (field)
如果 field 是任何一个 Truthy 值,

将评估为 truthy。您可以在 this answer.

中阅读更多关于不同值的真实性和虚假性的信息

所以,如果你想知道数组是否有一个特定的索引,那么你可以使用Object.prototype.hasOwnProperty,像这样

var array = [];
array[1] = undefined;

console.log(array[0]);
// undefined
console.log(array[1]);
// undefined
console.log(array.hasOwnProperty(0));
// false
console.log(array.hasOwnProperty(1));
// true

这里1处的元素定义为undefined,但是由于根本没有定义0,默认情况下,JavaScript returns undefined.

hasOwnProperty 调用检查当前对象是否确实具有索引 01.

"Best" 是一个相当主观的术语,所以让我们用一些 objective 标准来衡量它:

  1. 哪个更快?

    现实世界中,您会注意到,两者都不是。但是如果你真的想知道,measure your specific code你想支持的引擎。

  2. 哪个更容易阅读?

    这可能也是主观的。第二种形式 在 JavaScript 中非常 常见,FWIW.

  3. 哪个打字少?

    第二种明显比第一种短很多

  4. 哪个比较靠谱?

    鉴于您的用例,它们同样可靠,因为您要么根本不在数组中存储条目,要么存储非 null 对象引用。

    在相似但不同的用例中,您可能需要注意其中的差异:第一种形式 对于存在且不具有其中的值 undefined。第二种形式对于任何不是 falsey 的东西都是正确的。有几个假值:nullundefined0""NaN,当然还有 false。所以你不会使用第二种形式来决定数组中的某个位置是否有数字,因为 0 是一个数字但 if (0) 不会进入 [=20 的主体=].

    说到歧义,请注意关于“...对于存在但不包含值 undefined 的条目为真...”的评论,您给出的两个示例都没有区分 不存在的条目 和存在的值为 undefined 的条目。如果您需要在某些时候区分它们(同样,不是针对您提到的用例),您可以在数组上使用 hasOwnPropertyif (array.hasOwnProperty(row))

The second solution is shorter, so it could be quicker to execute, because JavaScript is an interpreted scripting language

这是一个错误的假设。大多数现代 JavaScript 引擎都是即时优化编译器。例如,V8(Chrome 中的引擎)是一个 两阶段 优化编译器:在第一遍中,它将您的 JavaScript 快速转换为机器代码,然后如果它识别出热点(运行 很多代码),它会返回并在那里进行更积极的优化。

我给你举个例子。希望它能帮助你感觉更清晰。

var arr = [];
arr[0] = 0;
arr[1] = undefined;
arr[2] = null;
arr[3] = NaN;
arr[4] = '';
arr[5] = false;

arr[11] = 1;
arr[12] = [];
arr[13] = {};
arr[14] = 'hello';  
arr[15] = true;  

if(arr[0]) //false but exists
if(arr[1]) //false but exists
if(arr[2]) //false but exists
if(arr[3]) //false but exists
if(arr[4]) //false but exists
if(arr[5]) //false but exists

if(arr[6]) //false and not exist
if(arr[7]) //false and not exist
if(arr[8]) //false and not exist
if(arr[9]) //false and not exist
if(arr[10]) //false and not exist  

if(arr[11]) //true and exists
if(arr[12]) //true and exists
if(arr[13]) //true and exists
if(arr[14]) //true and exists
if(arr[15]) //true and exists

一般来说,我建议您使用第二种解决方案来检查是否存在,因为它更短且更易于阅读。但是,它仍然在很大程度上取决于您的情况。确保您的选择不会在任何意外情况下失败。