Tester l'existence d'objects imbriqués
Bonjour,
Ca fait longtemp que je n'étais plus venu ici, mais j'aimerai partager une petite fonction que je viens de me coder pour tester si un sous-(sous-sous-...)objet existe dans un objet parent.
Exemple de cas :
Code:
var test = {level1: {level2: {level:'ok'} }};
Typiquement, si on ne sait pas si test et ses sous-objets existent, nous devrons tester de la façon :
Code:
1 2 3
| if(test && test.level1 && test.level1.level2){
alert(test.level1.level2.level3);
} |
Ce qui est fastidieux à écrire je trouve.
Je propose donc une première solution :
Code:
1 2 3 4 5 6 7
| function get_if_exist(str){
try{return eval(str)}
catch(e){return undefined}
}
// appel
alert(get_if_exist('test.level1.level2.level3')); |
Qui a pour principale contrainte que l'objet 'test' doit être global (ou du moins dans la porté de la fonction get_if_exist ... dépendant du comportement du (diabolique) "eval" selon la version du navigateur).
Je propose donc une seconde solution un peu plus compliquée :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function get_if_exist(obj){
var a=arguments, b=a.callee; // replace a.callee by the function name you choose, in this case : get_if_exist
// version 1 faisant appel à la version 2
if(a[1] && ~a[1].indexOf('.'))
return b.apply(this,[obj].concat(a[1].split('.')));
// version 2
return a.length==1 ? a[0] : (obj[a[1]] && b.apply(this,[obj[a[1]]].concat([].slice.call(a,2))));
}
// appel (version 1)
alert(get_if_exist(test,'level1.level2.level3'));
// ou alternative (version 2)
alert(get_if_exist(test,'level1','level2','level3')); |
Vous noterez que j'ai utilisé "callee" bien que déprécié en faveur du nom de la fonction, afin de laisser ceux qui reprendront ma fonction, l'utiliser en la nommant autrement (ou en ne la nommant pas du tout) sans avoir besoin de modifier son contenu pour déclencher l'appel récursif.
Pour le puristes, il suffit de modifier le contenu et de remplacer a.callee par le nom que vous aurez choisi (pour une fonction nommée).
Voila, faites-en bon usage.
:ccool: