Accès aux objets JavaScript imbriqués avec une clé de chaîne
J'ai une structure de données comme ceci :
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";
Part1name doit être rempli avec la valeur de someObject.part1.name
, qui est "Part 1". Même chose avec part2quantity qui a rempli avec 60.
Existe-t-il de toute façon pour y parvenir avec JavaScript pur ou JQuery?
28 réponses
Je viens de le faire basé 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;
}
Utilisation::
Object.byString(someObj, 'part3[0].name');
Voir une démo de travail à http://jsfiddle.net/alnitak/hEsys/
EDIT certains ont remarqué que ce code déclenchera une erreur si une chaîne est passée où les index les plus à gauche ne correspondent pas à une entrée correctement imbriquée dans l'objet. C'est une préoccupation VALIDE, mais à mon humble avis, il vaut mieux traiter avec un bloc try / catch
lors de l'appel, plutôt que d'avoir ceci la fonction renvoie silencieusement undefined
pour un index invalide.
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:
- ne peut pas utiliser de parenthèses (
[]
) pour les indices de tableau-bien que la spécification d'indices de tableau entre le jeton de séparation (par exemple,.
) fonctionne correctement comme indiqué ci-dessus.
Ceci est maintenant pris en charge par lodash en utilisant _.get(obj, property)
. Voir https://lodash.com/docs#get
Exemple des documents:
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 devrez 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';
}
}
Cela nécessitait que vous définissiez également des index de tableau avec une notation par points:
var part3name1 = "part3.0.name";
Cela facilite l'analyse.
DÉMO
Fonctionne pour les tableaux / tableaux à l'intérieur de l'objet. Défensif contre les valeurs invalides.
/**
* 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 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 le nombre faux, 0 et négatif et accepte les valeurs par défaut comme 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
Bonus:
À set un chemin d'accès (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}}}
tableau d'Accès 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/
Veuillez faire preuve de bon sens et de prudence lorsque vous utilisez le pouvoir d'eval. C'est un peu comme un sabre léger, si vous l'allumez, il y a 90% de chances que vous coupiez un membre. Ce n'est pas pour tout le monde.
Vous pouvez obtenir la valeur d'un membre d'objet profond avec une notation par points sans bibliothèque JavaScript externe avec l'astuce suivante:
new Function('_', 'return _.' + path)(obj);
Dans votre cas pour obtenir la valeur de part1.name
de someObject
Faites simplement:
new Function('_', 'return _.part1.name')(someObject);
Voici une simple démo de violon: https://jsfiddle.net/harishanchu/oq5esowf/
Ici, j'offre plus de moyens, qui semblent plus rapides à bien des égards:
Option 1: diviser la chaîne sur . ou [ ou] ou 'ou", inversez-le, sautez 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 de toutes, sauf eval
): Analyse de caractères de bas niveau (Pas de regex / split/etc, juste une analyse de caractères rapide).
Note: 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: (nouveau : option 2 développée 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 (performance sage qui est). Si vous avez des chemins de propriétés directement sous votre contrôle, il ne devrait pas y avoir de problèmes avec l'utilisation de 'eval' (surtout si la vitesse est souhaitée). 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" à tout, car il y a 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èmes du tout . Utiliser le bon outil pour le bon travail, c'est tout.
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"];
Qui fonctionneront tous les deux
Ou peut-être que vous demandez cela
var partName = "part1";
var nameStr = "name";
var part1name = someObject[partName][nameStr];
Enfin, vous pourriez demander ceci
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 propre, bien que j'ai trouvé cette réponse en cherchant la solution d'accéder aux propriétés AngularJS $scope par chemin de chaîne et avec une petite modification, il fait le travail:
$scope.resolve = function( path, obj ) {
return path.split('.').reduce( function( prev, curr ) {
return prev[curr];
}, obj || this );
}
Placez simplement cette fonction dans votre contrôleur racine et utilisez-la n'importe quelle portée enfant comme ceci:
$scope.resolve( 'path.to.any.object.in.scope')
C'est un one liner 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 encore 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);
Je n'ai pas encore trouvé de paquet pour faire toutes les opérations avec un chemin de chaîne, donc j'ai fini par écrire mon propre petit paquet rapide qui supporte les opérations insert (), get () (avec RETOUR par défaut), set () et remove ().
Vous pouvez utiliser la notation par points, les parenthèses, les indices de nombres, les propriétés de nombre de chaînes et les clés avec des caractères non word. Simple d'utilisation 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
Ou
console.log(get(obj, ['a', 'b', 'c'])); //foo
Il y a un module npm
maintenant pour faire ceci: https://github.com/erictrinh/safe-access
Exemple d'utilisation:
var access = require('safe-access');
access(very, 'nested.property.and.array[0]');
Juste au cas où, quelqu'un visite cette question en 2017 ou plus tard et cherche un moyen facile à retenir, Voici un article de blog élaboré sur accédant aux objets imbriqués en JavaScript sans être bamboozled par
Impossible de lire la propriété 'foo' undefined erreur
Accédez Aux Objets Imbriqués En Utilisant Array Reduce
Prenons cet exemple de structure
const user = {
id: 101,
email: 'jack@dev.com',
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éduire 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 gestion des types typy qui fait tout cela pour vous.
Avec typy, votre code ressemblera à ceci
const city = t(user, 'personalInfo.address[0].city').safeObject;
Avertissement: je suis l'auteur de ce paquet.
Cela ne verra probablement jamais le jour... mais ici, il est de toute façon.
- remplacez
[]
la syntaxe des crochets par.
- diviser sur
'
caractère - supprimer les chaînes vides
- trouver le chemin (sinon
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
/**
* 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;
}
Fonctionne 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")
Alors que réduire est bon, je suis surpris que personne n'utilise forEach:
function valueForKeyPath(obj, path){
const keys = path.split('.');
keys.forEach((key)=> obj = obj[key]);
return obj;
};
Si vous avez besoin d'accéder à différentes clés imbriquées sans le savoir au moment du codage (il sera trivial de les traiter), 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 de point 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 votre question...
Modifier
Je n'utiliserai pas une chaîne pour gérer une sorte de XPath query pour accéder à un la valeur de l'objet. Comme vous devez appeler une fonction pour analyser la requête et récupérer la valeur, je suivrais un autre chemin (pas:
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 êtes mal à l'aise avec les appliquer méthode
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éteur les vérifie pour vous pour les erreurs de syntaxe et ainsi de suite.
En passant, je pense qu'une simple affectation faite au bon moment sera suffisante...
Vient d'avoir la même question récemment et utilisé avec succès https://npmjs.org/package/tea-properties qui aussi set
Objet/tableaux imbriqués:
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
Les solutions ici sont juste pour accéder aux clés profondément imbriquées. J'en avais besoin pour accéder, ajouter, modifier et supprimer les clés. C'est 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 votrestring_path.split(".")
. -
type_of_function
: 0 pour accéder(ne passez aucune valeur àvalue
), 0 pour ajouter et modifier. 1 pour la suppression.
Au lieu d'une chaîne, Un tableau peut être utilisé pour adresser des objets imbriqués et des tableaux, par exemple: ["my_field", "another_field", 0, "last_field", 10]
Voici un exemple qui modifierait un champ basé sur cette représentation de tableau. J'utilise quelque chose comme ça dans react.js pour les champs d'entrée contrôlés qui modifient 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);
Sur la base d'une réponse précédente, j'ai créé une fonction qui peut également gérer les parenthèses. 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);
}
// (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"]));
Travailler avec 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...
Qu'en est-il de cette solution:
setJsonValue: function (json, field, val) {
if (field !== undefined){
try {
eval("json." + field + " = val");
}
catch(e){
;
}
}
}
Et celui-ci, pour obtenir:
getJsonValue: function (json, field){
var value = undefined;
if (field !== undefined) {
try {
eval("value = json." + field);
}
catch(e){
;
}
}
return value;
};
Probablement certains les considéreront comme dangereux, mais ils doivent être beaucoup plus rapides alors, en analysant la chaîne.
Construire à partir de la réponse D'Alnitak:
if(!Object.prototype.byString){
//NEW byString which can update values
Object.prototype.byString = function(s, v, o) {
var _o = o || this;
s = s.replace(/\[(\w+)\]/g, '.$1'); // CONVERT INDEXES TO PROPERTIES
s = s.replace(/^\./, ''); // STRIP A LEADING DOT
var a = s.split('.'); //ARRAY OF STRINGS SPLIT BY '.'
for (var i = 0; i < a.length; ++i) {//LOOP OVER ARRAY OF STRINGS
var k = a[i];
if (k in _o) {//LOOP THROUGH OBJECT KEYS
if(_o.hasOwnProperty(k)){//USE ONLY KEYS WE CREATED
if(v !== undefined){//IF WE HAVE A NEW VALUE PARAM
if(i === a.length -1){//IF IT'S THE LAST IN THE ARRAY
_o[k] = v;
}
}
_o = _o[k];//NO NEW VALUE SO JUST RETURN THE CURRENT VALUE
}
} else {
return;
}
}
return _o;
};
}
Cela vous permet de définir une valeur aussi bien!
, j'ai créé un mnp package et github avec ce même