Mam tablicę obiektów, które mogą lub nie być zaludnione tablicą w swoich właściwościach. Wywołanie $. (X, funkcja () {}) na null x powoduje błąd typu

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

Widziałem sugestie używania $ .extend na pustym obiekcie i przekazywania tej wartości do $. Oba te wydają się działać dla mnie i wydają się prostsze, czy są jakieś wady do każdego?

//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){});}

Drugi wydaje mi się najczystszy.

0
Pete 3 październik 2012, 23:22

5 odpowiedzi

Najlepsza odpowiedź

Możesz skorzystać z in operatora Sprawdź, czy właściwość istnieje w obiekcie.

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

Oraz użyj instanceof Operator do sprawdzenia przeciw prawidłowej zmiennej typu.

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

W przeciwieństwie do oceny zwarciowej, nie jest to podatne na wartości prawdów.

$.each(a[i].v || [], ...);
1
Alexander 3 październik 2012, 19:57

Możesz nawet najpierw skrócić

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

$.each Umieści kilka nadległych przedmiotów.

Moja rada polega na zrobieniu Null-Safe for Loop Wrapper Like:

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]);
  };
}

I rozważmy na pamięć podręczną a.length

0
Anton Rudeshko 3 październik 2012, 19:30

Prawdopodobnie masz na myśli undefined, a nie null. W JavaScript, zmienne, które jeszcze nie mają wartości, są ustawione na undefined.

Osobiście lubię rozwiązanie # 2 najlepiej. To właśnie zrobiłbym. Należy jednak pamiętać, że jeśli jest to kod, ktoś inny może utrzymywać w przyszłości, nie zaszkodzi mu przejść z metodą # 1. Metoda # 1 jest bardziej oczywista w tym, co robi, a zatem jest bardziej utrzymujący się przez kogoś, kto może być równie zaznaczony z koncepcją operatorów logicznych zwartych (np. ||).

Również metoda # 2 jest taka-nieco wolniejsza niż metoda # 1, ponieważ musi instancję instancji pustej tablicy, jeśli a[i].v jest falssy. Ale nad głową jest nieistotny, więc jeśli nie jest to kod krytyczny krytyczny lub krytyczny dla pamięci, masz w porządku z metodą # 2.

0
Pete 3 październik 2012, 19:33

Inną możliwością jest filtrowanie pierwszej tablicy.

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

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

Lub użyj rodzimych metod, aby zrobić to samo.

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

a.filter(hasV).forEach(doWork);
0
I Hate Lazy 3 październik 2012, 19:34

Jest to bardziej czytelna wersja (wykorzystuje jasne, pełne kontroli) tego, co możesz zrobić

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

Możesz także sprawdzić długość a[i].v dla dobrej miary, jeśli chcesz być naprawdę dobry!

0
SmokeyPHP 3 październik 2012, 19:37