Compte tenu de l'obj suivant:
var inputMapping = { nonNestedItem: "someItem here", sections: { general: "Some general section information" } };
"nonNestedItem"
une fonction pour get
ces données en passant dans une chaîne "nonNestedItem"
ou dans le cas niché "sections.general"
. Je dois utiliser un eval
et je me demandais s'il y avait peut-être une meilleure façon de le faire.
Voici ce que j'ai jusqu'ici et ça fonctionne bien. Mais améliorez!
function getNode(name) { var n = name.split("."); if (n.length === 1) { n = name[0]; } else { var isValid = true, evalStr = 'inputMapping'; for (var i=0;i<n.length;i++) { evalStr += '["'+ n[i] +'"]'; if (eval(evalStr) === undefined) { isValid = false; break; } } if (isValid) { // Do something like return the value } } }
Linky à Jsbin
Vous pouvez utiliser la fonction Array.prototype.reduce
comme celle-ci
var accessString = "sections.general"; console.log(accessString.split(".").reduce(function(previous, current) { return previous[current]; }, inputMapping));
Sortie
Some general section information
Si votre environnement ne prend pas en charge la reduce
, vous pouvez utiliser cette version récursive
function getNestedItem(currentObject, listOfKeys) { if (listOfKeys.length === 0 || !currentObject) { return currentObject; } return getNestedItem(currentObject[listOfKeys[0]], listOfKeys.slice(1)); } console.log(getNestedItem(inputMapping, "sections.general".split(".")));
Vous n'avez pas besoin d'utiliser eval()
ici. Vous pouvez simplement utiliser []
pour obtenir des valeurs d'un objet. Utilisez un objet temporaire pour contenir la valeur actuelle, puis mettez-la à jour chaque fois que vous avez besoin de la touche suivante.
function getNode(mapping, name) { var n = name.split("."); if (n.length === 1) { return mapping[name]; } else { var tmp = mapping; for (var i = 0; i < n.length; i++) { tmp = tmp[n[i]]; } return tmp; } }