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

时间:2015-04-25 11:02:05

标签: javascript undefined

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

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的布尔值,或类似的东西......

你对此有何看法?

3 个答案:

答案 0 :(得分:4)

您创建的数组称为稀疏数组。您可以在this answer中了解有关它的更多信息。

支票

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

可能无效。这个检查

if (field)
如果field是任何一个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会返回undefined

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

答案 1 :(得分:2)

"最佳"这是一个相当主观的术语,所以让我们抛出一些客观标准:

  1. 哪个更快?

    您在现实世界注意的方式都不是。但是如果你真的想知道你想要支持的引擎measure your specific code

  2. 哪个更容易阅读?

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

  3. 哪种打字少?

    第二种形式显然比第一种形式短很多。

  4. 哪个更可靠?

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

    在类似但不同的用例中,您可能需要警惕差异:第一种形式对于存在的条目是真的,并且没有值{{ 1}}在里面。第二种形式适用于任何不是 falsey 的形式。有几个假名值:undefinednullundefined0"",当然还有NaN。因此,您不会使用第二种形式来判断数组中某个位置是否有数字,因为false是一个数字,但0不会进入正文if (0)

    说到含糊不清,请注意关于" ...的评论对于存在的条目是真的,并且其中没有值if ..."您提供的示例中没有一个区分不存在的条目和存在值undefined的条目。如果您需要在某些时候区分这些(再次,不是您提到的用例),您可以在数组上使用undefinedhasOwnProperty

  5.   

    第二种解决方案更短,因此可以更快地执行,因为JavaScript是一种解释型脚本语言

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

答案 2 :(得分:2)

我会给你这个例子。希望它能让你感觉更清楚。

declare cur_item cursor for
select item_id
from   item
order by item_id;

declare cur_loc cursor for
select loc_id
from   location;

declare continue handler for not found set not_found = true;

set not_found = false;

open cur_item;

fetch cur_item into s_item;

read_item:
loop
    if not_found then
        leave read_item;
    end if;

    set d_opng_qty = 0;
    set d_opng_cost = 0;
    set d_cls_qty = 0;
    set d_cls_cost = 0;

    open cur_loc;

    fetch cur_loc into s_loc;

    read_loc:
    loop
        if not_found then
            leave read_loc;
        end if;

        -- For Opening Stock:
        select item_qty,
               item_cost
        into   d_opng_qty,
               d_opng_cost
        from   stock
        where  stock_dt < adt_from
        and    loc_id = s_loc
        and    item_id = s_item
        order by stock_dt desc
        limit 1;

        -- For Closing Stock:
        select item_qty,
               item_cost
        into   d_cls_qty,
               d_cls_cost
        from   stock
        where  stock_dt <= adt_to
        and    loc_id = s_loc
        and    item_id = s_item
        order by stock_dt desc
        limit 1;

        fetch cur_loc into s_loc;
    end loop;

    fetch cur_item into s_item;      
end loop;

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