0

我有一个对象数组,可能会或可能不会在其属性中填充一个数组。对 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){});}

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

4

5 回答 5

1

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

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

并且,使用instanceof运算符检查正确的变量类型。

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

与短路评估相比,这一评估不易受真值的影响。

$.each(a[i].v || [], ...);
于 2012-10-03T19:38:47.623 回答
0

您甚至可以快捷方式第一个到

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

$.each会给普通对象带来一些开销。

我的建议是制作一个这样的空安全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

于 2012-10-03T19:30:12.993 回答
0

你可能的意思是undefined,不是null。在 JavaScript 中,还没有值的变量被设置为undefined.

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

此外,方法 #2 比方法 #1 稍微慢一点,因为如果a[i].vfalsy ,它需要实例化一个空数组。但是开销可以忽略不计,因此除非出于某种原因这是性能关键或内存关键的代码,否则您可以使用方法 #2。

于 2012-10-03T19:33:52.323 回答
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);
于 2012-10-03T19:34:32.213 回答
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如果你想变得非常好,你也可以检查一下长度是否合适!

于 2012-10-03T19:37:30.473 回答