J'ai une structure de données comme celle-ci:
var someObject = {
'part1' : {
'name': 'Part 1',
'size': '20',
'qty' : '50'
},
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}, {
'name': 'Part 3B',
'size': '5',
'qty' : '20'
}, {
'name': 'Part 3C',
'size': '7.5',
'qty' : '20'
}
]
};
Et je voudrais accéder aux données en utilisant ces variables:
var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";
nom_partie doit être renseigné avec la valeur de someObject.part1.name
, qui correspond à «Partie 1». Même chose avec la quantité de part2 qui a rempli de 60.
Y a-t-il un moyen d'y parvenir avec du javascript pur ou avec JQuery?
Je viens de le créer en me basant sur un code similaire que j'avais déjà, il semble fonctionner:
Object.byString = function(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
o = o[k];
} else {
return;
}
}
return o;
}
Usage::
Object.byString(someObj, 'part3[0].name');
Voir une démonstration de travail sur http://jsfiddle.net/alnitak/hEsys/
EDIT certains ont remarqué que ce code jetterait une erreur en cas de transmission d'une chaîne où les index les plus à gauche ne correspondent pas à une entrée correctement imbriquée dans l'objet. Ceci est une préoccupation valable, mais il est préférable de s’adresser à IMHO avec un bloc try / catch
lors de l’appel, plutôt que de laisser cette fonction renvoyer en silence undefined
pour un index incorrect.
C'est la solution que j'utilise:
function resolve(path, obj=self, separator='.') {
var properties = Array.isArray(path) ? path : path.split(separator)
return properties.reduce((prev, curr) => prev && prev[curr], obj)
}
Exemple d'utilisation:
// accessing property path on global scope
resolve("document.body.style.width")
// or
resolve("style.width", document.body)
// accessing array indexes
// (someObject has been defined in the question)
resolve("part3.0.size", someObject) // returns '10'
// accessing non-existent properties
// returns undefined when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})
// accessing properties with unusual keys by changing the separator
var obj = { object: { 'a.property.name.with.periods': 42 } }
resolve('object->a.property.name.with.periods', obj, '->') // returns 42
// accessing properties with unusual keys by passing a property name array
resolve(['object', 'a.property.name.with.periods'], obj) // returns 42
Limites:
[]
) pour les index de tableau - bien que spécifier des index de tableau entre le jeton séparateur (par exemple, .
) fonctionne correctement, comme indiqué ci-dessus. Ceci est maintenant supporté par lodash en utilisant _.get(obj, property)
. Voir https://lodash.com/docs#get
Exemple tiré de la documentation:
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c');
// → 3
_.get(object, ['a', '0', 'b', 'c']);
// → 3
_.get(object, 'a.b.c', 'default');
// → 'default'
Vous devriez analyser la chaîne vous-même:
function getProperty(obj, prop) {
var parts = prop.split('.');
if (Array.isArray(parts)) {
var last = parts.pop(),
l = parts.length,
i = 1,
current = parts[0];
while((obj = obj[current]) && i < l) {
current = parts[i];
i++;
}
if(obj) {
return obj[last];
}
} else {
throw 'parts is not valid array';
}
}
Pour cela, vous devez également définir des index de tableau avec une notation par points:
var part3name1 = "part3.0.name";
Cela facilite l'analyse.
Fonctionne aussi pour les tableaux/tableaux à l'intérieur de l'objet.
/**
* Retrieve nested item from object/array
* @param {Object|Array} obj
* @param {String} path dot separated
* @param {*} def default value ( if result undefined )
* @returns {*}
*/
function path(obj, path, def){
var i, len;
for(i = 0,path = path.split('.'), len = path.length; i < len; i++){
if(!obj || typeof obj !== 'object') return def;
obj = obj[path[i]];
}
if(obj === undefined) return def;
return obj;
}
//////////////////////////
// TEST //
//////////////////////////
var arr = [true, {'sp ace': true}, true]
var obj = {
'sp ace': true,
arr: arr,
nested: {'dotted.str.ing': true},
arr3: arr
}
shouldThrow(`path(obj, "arr.0")`);
shouldBeDefined(`path(obj, "arr[0]")`);
shouldBeEqualToNumber(`path(obj, "arr.length")`, 3);
shouldBeTrue(`path(obj, "sp ace")`);
shouldBeEqualToString(`path(obj, "none.existed.prop", "fallback")`, "fallback");
shouldBeTrue(`path(obj, "nested['dotted.str.ing'])`);
<script src="https://cdn.rawgit.com/coderek/e7b30bac7634a50ad8fd/raw/174b6634c8f57aa8aac0716c5b7b2a7098e03584/js-test.js"></script>
ES6 : Une seule ligne dans Vanila JS (elle renvoie null si elle ne trouve pas au lieu de donner une erreur):
'path.string'.split('.').reduce((p,c)=>p&&p[c]||null, MyOBJ)
ou exemple:
'a.b.c'.split('.').reduce((p,c)=>p&&p[c]||null, {a:{b:{c:1}}})
Pour une fonction prête à l'emploi qui reconnaît également les nombres faux, 0 et négatifs et accepte les valeurs par défaut en tant que paramètre:
const resolvePath = (object, path, defaultValue) => path
.split('.')
.reduce((o, p) => o ? o[p] : defaultValue, object)
Exemple à utiliser:
resolvePath(window,'document.body') => <body>
resolvePath(window,'document.body.xyz') => undefined
resolvePath(window,'document.body.xyz', null) => null
resolvePath(window,'document.body.xyz', 1) => 1
Prime:
Pour définir un chemin (demandé par @ rob-gordon), vous pouvez utiliser:
const setPath = (object, path, value) => path
.split('.')
.reduce((o,p) => o[p] = path.split('.').pop() === p ? value : o[p] || {}, object)
Exemple:
let myVar = {}
setPath(myVar, 'a.b.c', 42) => 42
console.log(myVar) => {a: {b: {c: 42}}}
Accéder au tableau avec []:
const resolvePath = (object, path, defaultValue) => path
.split(/[\.\[\]\'\"]/)
.filter(p => p)
.reduce((o, p) => o ? o[p] : defaultValue, object)
exemple
const myVar = {a:{b:[{c:1}]}}
resolvePath(myVar,'a.b[0].c') => 1
resolvePath(myVar,'a["b"][\'0\'].c') => 1
en utilisant eval:
var part1name = eval("someObject.part1.name");
wrap pour retourner undefined en cas d'erreur
function path(obj, path) {
try {
return eval("obj." + path);
} catch(e) {
return undefined;
}
}
http://jsfiddle.net/shanimal/b3xTw/
Faites preuve de bon sens et de prudence lorsque vous utilisez le pouvoir d’eval. C'est un peu comme un sabre laser. Si vous l'allumez, vous avez 90% de chances de vous trancher un membre. Ce n'est pas pour tout le monde.
Vous pouvez obtenir la valeur d'un membre d'objet profond avec la notation pointée sans aucune bibliothèque JavaScript externe avec la simple astuce suivante:
new Function('_', 'return _.' + path)(obj);
Dans votre cas, pour obtenir la valeur de part1.name
à partir de someObject
, il suffit de:
new Function('_', 'return _.part1.name')(someObject);
Voici une simple démo de violon: https://jsfiddle.net/harishanchu/oq5esowf/
Ici, je propose plus de moyens, qui semblent plus rapides à bien des égards:
Option 1: scinder la chaîne. ou [ou] ou 'ou ", inversez-le, ignorez les éléments vides.
function getValue(path, Origin) {
if (Origin === void 0 || Origin === null) Origin = self ? self : this;
if (typeof path !== 'string') path = '' + path;
var parts = path.split(/\[|\]|\.|'|"/g).reverse(), name; // (why reverse? because it's usually faster to pop off the end of an array)
while (parts.length) { name=parts.pop(); if (name) Origin=origin[name]; }
return Origin;
}
Option 2 (la plus rapide, à l'exception de eval
): analyse des caractères de bas niveau (pas de regex/split/etc, juste une analyse rapide des caractères) .Remarque: celui-ci ne prend pas en charge les guillemets pour les index.
function getValue(path, Origin) {
if (Origin === void 0 || Origin === null) Origin = self ? self : this;
if (typeof path !== 'string') path = '' + path;
var c = '', pc, i = 0, n = path.length, name = '';
if (n) while (i<=n) ((c = path[i++]) == '.' || c == '[' || c == ']' || c == void 0) ? (name?(Origin = Origin[name], name = ''):(pc=='.'||pc=='['||pc==']'&&c==']'?i=n+2:void 0),pc=c) : name += c;
if (i==n+2) throw "Invalid path: "+path;
return Origin;
} // (around 1,000,000+/- ops/sec)
Option 3: (new: option 2 étendue pour prendre en charge les guillemets - un peu plus lent, mais toujours rapide))
function getValue(path, Origin) {
if (Origin === void 0 || Origin === null) Origin = self ? self : this;
if (typeof path !== 'string') path = '' + path;
var c, pc, i = 0, n = path.length, name = '', q;
while (i<=n)
((c = path[i++]) == '.' || c == '[' || c == ']' || c == "'" || c == '"' || c == void 0) ? (c==q&&path[i]==']'?q='':q?name+=c:name?(origin?origin=Origin[name]:i=n+2,name='') : (pc=='['&&(c=='"'||c=="'")?q=c:pc=='.'||pc=='['||pc==']'&&c==']'||pc=='"'||pc=="'"?i=n+2:void 0), pc=c) : name += c;
if (i==n+2 || name) throw "Invalid path: "+path;
return Origin;
}
JSPerf: http://jsperf.com/ways-to-dereference-a-delimited-property-string/3
"eval (...)" est toujours roi (en termes de performances). Si vous avez des chemins de propriété directement sous votre contrôle, l'utilisation de 'eval' ne devrait poser aucun problème (surtout si vous souhaitez utiliser la vitesse). Si vous tirez des chemins de propriété "sur le fil" ( sur la ligne !? lol: P), alors oui, utilisez autre chose pour être sûr. Seul un idiot dirait de ne jamais utiliser "eval" du tout, car il ya de bonnes raisons quand l’utiliser. En outre, "Il est utilisé dans l'analyseur JSON de Doug Crockford ." Si l'entrée est sûre, alors pas de problème du tout. Utilisez le bon outil pour le bon travail, c'est tout.
Cela ne verra probablement jamais la lumière du jour ... mais le voilà quand même.
[]
par .
.
undefined
)// "one liner" (ES6)
const deep_value = (obj, path) =>
path
.replace(/\[|\]\.?/g, '.')
.split('.')
.filter(s => s)
.reduce((acc, val) => acc && acc[val], obj);
// ... and that's it.
var someObject = {
'part1' : {
'name': 'Part 1',
'size': '20',
'qty' : '50'
},
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}
// ...
]
};
console.log(deep_value(someObject, "part1.name")); // Part 1
console.log(deep_value(someObject, "part2.qty")); // 60
console.log(deep_value(someObject, "part3[0].name")); // Part 3A
Je pense que vous demandez ceci:
var part1name = someObject.part1.name;
var part2quantity = someObject.part2.qty;
var part3name1 = someObject.part3[0].name;
Vous pourriez demander ceci:
var part1name = someObject["part1"]["name"];
var part2quantity = someObject["part2"]["qty"];
var part3name1 = someObject["part3"][0]["name"];
Ce qui fonctionnera
Ou peut-être que vous demandez ceci
var partName = "part1";
var nameStr = "name";
var part1name = someObject[partName][nameStr];
Enfin, vous pourriez demander cela
var partName = "part1.name";
var partBits = partName.split(".");
var part1name = someObject[partBits[0]][partBits[1]];
L'approche de Speigg est très soignée et nette, même si j'ai trouvé cette réponse tout en cherchant la solution pour accéder aux propriétés de la portée AngularJS $ par chemin de chaîne et avec un peu de modification, cela fonctionne:
$scope.resolve = function( path, obj ) {
return path.split('.').reduce( function( prev, curr ) {
return prev[curr];
}, obj || this );
}
Il suffit de placer cette fonction dans votre contrôleur racine et de l’utiliser avec n’importe quelle portée enfant comme celle-ci:
$scope.resolve( 'path.to.any.object.in.scope')
C'est un paquebot avec lodash.
const deep = { l1: { l2: { l3: "Hello" } } };
const prop = "l1.l2.l3";
const val = _.reduce(prop.split('.'), function(result, value) { return result ? result[value] : undefined; }, deep);
// val === "Hello"
Ou même mieux ...
const val = _.get(deep, prop);
Ou version ES6 avec réduction ...
const val = prop.split('.').reduce((r, val) => { return r ? r[val] : undefined; }, deep);
Juste au cas où quiconque visiterait cette question en 2017 ou plus tard et recherchant un moyen facile à mémoriser, voici un article de blog élaboré sur Accès aux objets imbriqués en JavaScript sans être embrouillé
Impossible de lire la propriété 'foo' d'une erreur non définie
Prenons cet exemple de structure
const user = {
id: 101,
email: '[email protected]',
personalInfo: {
name: 'Jack',
address: [{
line1: 'westwish st',
line2: 'washmasher',
city: 'wallas',
state: 'WX'
}]
}
}
Pour pouvoir accéder aux tableaux imbriqués, vous pouvez écrire votre propre tableau, réduisez util.
const getNestedObject = (nestedObj, pathArr) => {
return pathArr.reduce((obj, key) =>
(obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}
// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);
// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'address', 0, 'city']);
// this will return the city from the first address item.
Il existe également une excellente bibliothèque minimale de type typy qui fait tout cela pour vous.
Avec typy, votre code ressemblera à ceci
const city = t(user, 'personalInfo.address[0].city').safeObject;
Disclaimer: Je suis l'auteur de ce paquet.
Je n'ai pas encore trouvé de paquet pour faire toutes les opérations avec un chemin de chaîne, alors j'ai fini par écrire mon propre petit paquet rapide qui supporte insert (), get () (avec return,) (set) ) opérations.
Vous pouvez utiliser la notation par points, les crochets, les index de nombre, les propriétés de numéro de chaîne et les clés avec des caractères autres que Word. Utilisation simple ci-dessous:
> var jsocrud = require('jsocrud');
...
// Get (Read) ---
> var obj = {
> foo: [
> {
> 'key w/ non-Word chars': 'bar'
> }
> ]
> };
undefined
> jsocrud.get(obj, '.foo[0]["key w/ non-Word chars"]');
'bar'
Fonction simple permettant un chemin de chaîne ou de tableau.
function get(obj, path) {
if(typeof path === 'string') path = path.split('.');
if(path.length === 0) return obj;
return get(obj[path[0]], path.slice(1));
}
const obj = {a: {b: {c: 'foo'}}};
console.log(get(obj, 'a.b.c')); //foo
OR
console.log(get(obj, ['a', 'b', 'c'])); //foo
/**
* Access a deep value inside a object
* Works by passing a path like "foo.bar", also works with nested arrays like "foo[0][1].baz"
* @author Victor B. https://Gist.github.com/victornpb/4c7882c1b9d36292308e
* Unit tests: http://jsfiddle.net/Victornpb/0u1qygrh/
*/
function getDeepVal(obj, path) {
if (typeof obj === "undefined" || obj === null) return;
path = path.split(/[\.\[\]\"\']{1,2}/);
for (var i = 0, l = path.length; i < l; i++) {
if (path[i] === "") continue;
obj = obj[path[i]];
if (typeof obj === "undefined" || obj === null) return;
}
return obj;
}
Marche avec
getDeepVal(obj,'foo.bar')
getDeepVal(obj,'foo.1.bar')
getDeepVal(obj,'foo[0].baz')
getDeepVal(obj,'foo[1][2]')
getDeepVal(obj,"foo['bar'].baz")
getDeepVal(obj,"foo['bar']['baz']")
getDeepVal(obj,"foo.bar.0.baz[1]['2']['w'].aaa[\"f\"].bb")
Il existe maintenant un module npm
pour cela: https://github.com/erictrinh/safe-access
Exemple d'utilisation:
var access = require('safe-access');
access(very, 'nested.property.and.array[0]');
Bien que réduire, c'est bien, je suis surpris que personne ne l'ait utiliséChaque:
function valueForKeyPath(obj, path){
const keys = path.split('.');
keys.forEach((key)=> obj = obj[key]);
return obj;
};
Underscore
's property
ou propertyOf
:var test = {
foo: {
bar: {
baz: 'hello'
}
}
}
var string = 'foo.bar.baz';
// document.write(_.propertyOf(test)(string.split('.')))
document.write(_.property(string.split('.'))(test));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
Bonne chance...
L'extension de Mohamad Hamouday 'Answer remplira les clés manquantes
function Object_Manager(obj, Path, value, Action, strict)
{
try
{
if(Array.isArray(Path) == false)
{
Path = [Path];
}
let level = 0;
var Return_Value;
Path.reduce((a, b)=>{
console.log(level,':',a, '|||',b)
if (!strict){
if (!(b in a)) a[b] = {}
}
level++;
if (level === Path.length)
{
if(Action === 'Set')
{
a[b] = value;
return value;
}
else if(Action === 'Get')
{
Return_Value = a[b];
}
else if(Action === 'Unset')
{
delete a[b];
}
}
else
{
return a[b];
}
}, obj);
return Return_Value;
}
catch(err)
{
console.error(err);
return obj;
}
}
Exemple
obja = {
"a": {
"b":"nom"
}
}
// Set
path = "c.b" // Path does not exist
Object_Manager(obja,path.split('.'), 'test_new_val', 'Set', false);
// Expected Output: Object { a: Object { b: "nom" }, c: Object { b: "test_new_value" } }
Sur la base d’une réponse précédente, j’ai créé une fonction qui peut également gérer les crochets. Mais pas de points à l'intérieur en raison de la scission.
function get(obj, str) {
return str.split(/\.|\[/g).map(function(crumb) {
return crumb.replace(/\]$/, '').trim().replace(/^(["'])((?:(?!\1)[^\\]|\\.)*?)\1$/, (match, quote, str) => str.replace(/\\(\\)?/g, "$1"));
}).reduce(function(obj, prop) {
return obj ? obj[prop] : undefined;
}, obj);
}
Inspiré par la réponse de @ webjay: https://stackoverflow.com/a/46008856/4110122
J'ai créé cette fonction que vous pouvez utiliser pour Get/Set/Unset n’importe quelle valeur dans un objet
function Object_Manager(obj, Path, value, Action)
{
try
{
if(Array.isArray(Path) == false)
{
Path = [Path];
}
let level = 0;
var Return_Value;
Path.reduce((a, b)=>{
level++;
if (level === Path.length)
{
if(Action === 'Set')
{
a[b] = value;
return value;
}
else if(Action === 'Get')
{
Return_Value = a[b];
}
else if(Action === 'Unset')
{
delete a[b];
}
}
else
{
return a[b];
}
}, obj);
return Return_Value;
}
catch(err)
{
console.error(err);
return obj;
}
}
Pour l'utiliser:
// Set
Object_Manager(Obj,[Level1,Level2,Level3],New_Value, 'Set');
// Get
Object_Manager(Obj,[Level1,Level2,Level3],'', 'Get');
// Unset
Object_Manager(Obj,[Level1,Level2,Level3],'', 'Unset');
// (IE9+) Two steps
var pathString = "[0]['property'].others[3].next['final']";
var obj = [{
property: {
others: [1, 2, 3, {
next: {
final: "SUCCESS"
}
}]
}
}];
// Turn string to path array
var pathArray = pathString
.replace(/\[["']?([\w]+)["']?\]/g,".$1")
.split(".")
.splice(1);
// Add object prototype method
Object.prototype.path = function (path) {
try {
return [this].concat(path).reduce(function (f, l) {
return f[l];
});
} catch (e) {
console.error(e);
}
};
// usage
console.log(obj.path(pathArray));
console.log(obj.path([0,"doesNotExist"]));
Au lieu d’une chaîne de caractères, un tableau peut être utilisé pour adresser des objets et des tableaux imbriqués, par exemple: ["my_field", "another_field", 0, "last_field", 10]
Voici un exemple qui modifierait un champ en fonction de cette représentation sous forme de tableau. J'utilise quelque chose comme ça dans react.js pour les champs d'entrée contrôlés qui changent l'état des structures imbriquées.
let state = {
test: "test_value",
nested: {
level1: "level1 value"
},
arr: [1, 2, 3],
nested_arr: {
arr: ["buh", "bah", "foo"]
}
}
function handleChange(value, fields) {
let update_field = state;
for(var i = 0; i < fields.length - 1; i++){
update_field = update_field[fields[i]];
}
update_field[fields[fields.length-1]] = value;
}
handleChange("update", ["test"]);
handleChange("update_nested", ["nested","level1"]);
handleChange(100, ["arr",0]);
handleChange('changed_foo', ["nested_arr", "arr", 3]);
console.log(state);
Les solutions présentées ici ne servent qu'à accéder aux clés profondément imbriquées. J'avais besoin d'un pour accéder, ajouter, modifier et supprimer les clés. Voici ce que je suis venu avec:
var deepAccessObject = function(object, path_to_key, type_of_function, value){
switch(type_of_function){
//Add key/modify key
case 0:
if(path_to_key.length === 1){
if(value)
object[path_to_key[0]] = value;
return object[path_to_key[0]];
}else{
if(object[path_to_key[0]])
return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
else
object[path_to_key[0]] = {};
}
break;
//delete key
case 1:
if(path_to_key.length === 1){
delete object[path_to_key[0]];
return true;
}else{
if(object[path_to_key[0]])
return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
else
return false;
}
break;
default:
console.log("Wrong type of function");
}
};
path_to_key
: chemin dans un tableau. Vous pouvez le remplacer par votre string_path.split(".")
.type_of_function
: 0 pour accéder (ne passez aucune valeur à value
), 0 pour ajouter et modifier. 1 pour supprimer.Je développe une boutique en ligne avec React. J'ai essayé de modifier les valeurs dans l'objet d'état copié pour mettre à jour l'état d'origine avec cet objet lors de l'envoi. Les exemples ci-dessus n'ont pas fonctionné pour moi, car la plupart d'entre eux modifient la structure d'un objet copié. J'ai trouvé un exemple de travail de la fonction d'accès et de modification des valeurs des propriétés d'objet imbriquées profondes: https://lowrey.me/create-an-object-by-path-in-javascript-2/ le voici :
const createPath = (obj, path, value = null) => {
path = typeof path === 'string' ? path.split('.') : path;
let current = obj;
while (path.length > 1) {
const [head, ...tail] = path;
path = tail;
if (current[head] === undefined) {
current[head] = {};
}
current = current[head];
}
current[path[0]] = value;
return obj;
};
Si vous devez accéder à différentes clés imbriquées sans le savoir au moment du codage (il sera facile de les adresser), vous pouvez utiliser l'accesseur de notation de tableau:
var part1name = someObject['part1']['name'];
var part2quantity = someObject['part2']['qty'];
var part3name1 = someObject['part3'][0]['name'];
Ils sont équivalents à l'accesseur de notation par points et peuvent varier au moment de l'exécution, par exemple:
var part = 'part1';
var property = 'name';
var part1name = someObject[part][property];
est équivalent à
var part1name = someObject['part1']['name'];
ou
var part1name = someObject.part1.name;
J'espère que cette adresse répond à votre question ...
MODIFIER
Je n'utiliserai pas une chaîne pour conserver une sorte de xpath query pour accéder à une valeur d'objet . Comme vous devez appeler une fonction pour analyser la requête et récupérer la valeur, je suivrais un autre chemin
var part1name = function(){ return this.part1.name; }
var part2quantity = function() { return this['part2']['qty']; }
var part3name1 = function() { return this.part3[0]['name'];}
// usage: part1name.apply(someObject);
ou, si vous n'êtes pas à l'aise avec la méthode apply
var part1name = function(obj){ return obj.part1.name; }
var part2quantity = function(obj) { return obj['part2']['qty']; }
var part3name1 = function(obj) { return obj.part3[0]['name'];}
// usage: part1name(someObject);
Les fonctions sont plus courtes, plus claires, l’interprète les vérifie pour vous pour des erreurs de syntaxe et ainsi de suite.
À propos, j’estime qu’une simple mission faite au bon moment sera suffisante ...
Je viens juste de poser la même question récemment et j'ai utilisé avec succès https://npmjs.org/package/tea-properties qui set
également objet/tableau imbriqué:
obtenir:
var o = {
prop: {
arr: [
{foo: 'bar'}
]
}
};
var properties = require('tea-properties');
var value = properties.get(o, 'prop.arr[0].foo');
assert(value, 'bar'); // true
ensemble:
var o = {};
var properties = require('tea-properties');
properties.set(o, 'prop.arr[0].foo', 'bar');
assert(o.prop.arr[0].foo, 'bar'); // true