对象属性上的$ .each()可能为null

时间:2012-10-03 19:22:20

标签: javascript jquery

我有一个对象数组,可能会也可能不会在其属性中填充数组。在null x上调用$ .each(x,function(){})会导致类型错误

try{
  var a = {};
  $.each(a.doesnotexist,function(k,v){})
} catch(e) {
  console.log(e.message)
}

我见过在空对象上使用$ .extend并将该值传递给$ .each()的建议。这两个似乎对我有用,看起来更简单,是否有任何缺点?

//some test values, not guaranteed properties are populated
var a = [
  {v: [1,2,3,4,5], w: [1,2,3,4,5,6]},
  {v: [1,2,3,4,5]},
  {w: [1,2,3,4,5]},
  {v: [1,2,3], w: []},
  {v: null}
];

for (i =0; i < a.length; i++) {if (a[i].v) $.each(a[i].v,function(k,v){});}
for (i =0; i < a.length; i++) {$.each(a[i].v||[],function(k,v){});}

第二个对我来说似乎最干净。

5 个答案:

答案 0 :(得分:1)

您可以使用in operator来检查对象中是否存在属性。

for (var i = 0; i < a.length; ++i) {
  if ("v" in a[i]){ 
    $.each(a[i].v, function(k,v) {
      ...
    });
  }
}

并使用instanceof operator检查正确的变量类型。

if ("v" in a[i] && a[i].v instanceof Array) { ... } 

与短路评估相反,这种评估不易受到真正的影响。

$.each(a[i].v || [], ...);

答案 1 :(得分:0)

您甚至可以将第一个快捷方式设为

a[i].v && $.each(a[i].v, function(k,v){});

$.each会对普通对象产生一些开销。

我的建议是制作一个类似于null的for循环包装器:

function nullsafeForEach(arr, fun) {
  var i, len;
  if (!arr || !arr.length || !fun) {
    return;
  }
  for (i = 0, len = arr.length; i < len; ++i) {
    fun(arr[i]);
  };
}

并考虑缓存a.length

答案 2 :(得分:0)

您可能是undefined,而不是null。在JavaScript中,尚未包含值的变量设置为undefined

就个人而言,我最喜欢解决方案#2。这就是我要做的。但是,您应该记住,如果这是其他人可能在将来维护的代码,那么使用方法#1并不会有什么坏处。方法#1在其正在进行的操作中更为明显,因此对于可能不熟悉逻辑运算符短路概念的人(例如||)更易于维护。

此外,方法#2比方法#1慢得多,因为如果a[i].vfalsy,它需要实例化一个空数组。但是开销可以忽略不计,所以除非出于某些原因这是性能关键或内存关键代码,否则你对方法#2没问题。

答案 3 :(得分:0)

另一种可能性是过滤第一个数组。

function hasV(item) { return !!item.v; }
function doWork(k, v) { /* do your work */ }

$.each($.grep(a, hasV), doWork);

或使用原生方法做同样的事情。

function hasV(item) { return !!item.v; }
function doWork(v, k) { /* do your work */ }

a.filter(hasV).forEach(doWork);

答案 4 :(得分:0)

这是一个更易读的版本(使用清晰,详细的检查),你可能想做什么

for(var i in a)
{
    if(typeof a[i] == 'object' && typeof a[i].v != 'undefined')
    {
        $.each(a[i].v,function(k,v){  });
    }
}

如果你想要真的很好,你还可以检查a[i].v的长度以获得良好的衡量标准!