J'essaie d'accéder à une propriété d'un objet en utilisant un nom dynamique. Est-ce possible?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
J'essaie d'accéder à une propriété d'un objet en utilisant un nom dynamique. Est-ce possible?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Réponses:
Il existe deux façons d'accéder aux propriétés d'un objet:
something.bar
something['bar']
La valeur entre crochets peut être n'importe quelle expression. Par conséquent, si le nom de la propriété est stocké dans une variable, vous devez utiliser la notation entre crochets:
var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected
Voici ma solution:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Exemples d'utilisation:
resolve("document.body.style.width")
// or
resolve("style.width", document.body)
// or even use array indexes
// (someObject has been defined in the question)
resolve("part.0.size", someObject)
// returns null when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})
En javascript, nous pouvons accéder avec:
foo.bar
foo[someVar]
oufoo["string"]
Mais seul le deuxième cas permet d'accéder dynamiquement aux propriétés:
var foo = { pName1 : 1, pName2 : [1, {foo : bar }, 3] , ...}
var name = "pName"
var num = 1;
foo[name + num]; // 1
// --
var a = 2;
var b = 1;
var c = "foo";
foo[name + a][b][c]; // bar
Voici un exemple ES6 de la façon dont vous pouvez accéder à la propriété d'un objet à l'aide d'un nom de propriété qui a été généré dynamiquement en concaténant deux chaînes.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
C'est ce qu'on appelle les noms de propriété calculés
Vous pouvez y parvenir de différentes manières.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
La notation entre crochets est particulièrement puissante car elle vous permet d'accéder à une propriété basée sur une variable:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
Cela peut être étendu au bouclage sur chaque propriété d'un objet. Cela peut sembler redondant en raison de nouvelles constructions JavaScript telles que pour ... de ..., mais aide à illustrer un cas d'utilisation:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
La notation par points et par crochets fonctionne également comme prévu pour les objets imbriqués:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Déstructuration d'objets
Nous pourrions également considérer la déstructuration d'objet comme un moyen d'accéder à une propriété dans un objet, mais comme suit:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
let prop = 'last';
let { bar, baz, [prop]: customName } = foo;
// bar = 'Hello World'
// baz = 'How are you doing?'
// customName = 'Quite alright'
Vous pouvez le faire comme ceci en utilisant Lodash get
_.get(object, 'a[0].b.c');
J'ai pris en considération les commentaires ci-dessous et je suis d'accord. Eval est à éviter.
L'accès aux propriétés de la racine dans l'objet est facile à réaliser obj[variable]
, mais obtenir des emboîtements complique la chose. Ne pas écrire de code déjà écrit que je suggère d'utiliser lodash.get
.
Exemple
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get peut être utilisé de différentes manières, voici le lien vers la documentation lodash.get
eval
autant que possible. stackoverflow.com/questions/86513/…
eval
pour quelque chose d'aussi banal que d'accéder à des propriétés est tout simplement exagéré et à peine recommandé en aucune circonstance. Quel est le "problème"? obj['nested']['test']
fonctionne très bien et ne vous oblige pas à incorporer du code dans des chaînes.
obj['nested']['value']
- rappelez-vous les enfants, eval est mauvais!
_.get
à la table. Je pense que cette réponse mérite maintenant des votes positifs plutôt que des votes négatifs. C'est peut-être exagéré, mais il est bon de savoir qu'il existe.
Chaque fois que vous devez accéder dynamiquement à une propriété, vous devez utiliser un crochet pour accéder à la propriété et non à "." opérateur
Syntaxe: objet [propriété]
const something = { bar: "Foobar!" };
const foo = 'bar';
// something.foo; -- not correct way at it is expecting foo as proprty in something={ foo: "value"};
// correct way is something[foo]
alert( something[foo])
Je suis tombé sur un cas où je pensais que je voulais passer l '"adresse" d'une propriété d'objet en tant que données à une autre fonction et remplir l'objet (avec AJAX), faire une recherche dans le tableau d'adresses et afficher dans cette autre fonction. Je ne pouvais pas utiliser la notation par points sans faire des acrobaties de chaînes, j'ai donc pensé qu'un tableau pourrait être agréable à passer à la place. J'ai fini par faire quelque chose de différent de toute façon, mais je semblais lié à ce post.
Voici un exemple d'un objet de fichier de langue comme celui dont je voulais des données:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
Je voulais pouvoir passer un tableau tel que: ["audioPlayer", "contrôles", "stop"] pour accéder au texte de la langue, "stop" dans ce cas.
J'ai créé cette petite fonction qui recherche le paramètre d'adresse (le moins) "le moins spécifique" et réaffecte l'objet renvoyé à lui-même. Il est ensuite prêt à rechercher le paramètre d'adresse suivant le plus spécifique, s'il en existe un.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
usage:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
Cela devient intéressant lorsque vous devez également passer des paramètres à cette fonction.
Code jsfiddle
var obj = {method:function(p1,p2,p3){console.log("method:",arguments)}}
var str = "method('p1', 'p2', 'p3');"
var match = str.match(/^\s*(\S+)\((.*)\);\s*$/);
var func = match[1]
var parameters = match[2].split(',');
for(var i = 0; i < parameters.length; ++i) {
// clean up param begninning
parameters[i] = parameters[i].replace(/^\s*['"]?/,'');
// clean up param end
parameters[i] = parameters[i].replace(/['"]?\s*$/,'');
}
obj[func](parameters); // sends parameters as array
obj[func].apply(this, parameters); // sends parameters as individual values
Ce simple morceau de code peut vérifier l'existence de variables / valeurs profondément imbriquées sans avoir à vérifier chaque variable en cours de route ...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Ex. - un tableau d'objets profondément imbriqués:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
Au lieu de :
if(a && a[0] && a[0].b && a[0].b[0] && a[0].b[0].b && a[0].b[0].b[0] && a[0].b[0].b[0].d && a[0].b[0].b[0].d == 2 ) // true
Nous pouvons maintenant:
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
À votre santé!
J'ai posé une question qui a un peu dupliqué sur ce sujet il y a quelque temps, et après des recherches excessives, et voyant beaucoup d'informations manquantes qui devraient être ici, je pense que j'ai quelque chose de précieux à ajouter à cet ancien article.
let properyValue = element.style['enter-a-property'];
Cependant, je vais rarement dans cette voie car cela ne fonctionne pas sur les valeurs de propriété attribuées via les feuilles de style. Pour vous donner un exemple, je vais démontrer avec un peu de pseudo-code.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
En utilisant l'exemple de code ci-dessus; si la propriété width de l'élément div qui était stocké dans la variable 'elem' était stylisée dans une feuille de style CSS, et non stylisée à l'intérieur de sa balise HTML, vous obtiendrez sans aucun doute une valeur de retour indéfinie stockée à l'intérieur de la variable cssProp. La valeur indéfinie se produit parce que pour obtenir la valeur correcte, le code écrit à l'intérieur d'une feuille de style CSS doit être calculé afin d'obtenir la valeur, par conséquent; vous devez utiliser une méthode qui calculera la valeur de la propriété dont la valeur se trouve dans la feuille de style.
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc Cela donne un bon exemple et vous permet de jouer avec, cependant, ce lien Le document Mozilla CSS getComputedValue parle de la fonction getComputedValue en détail, et devrait être lu par tout développeur en herbe qui n'est pas totalement clair sur ce sujet.
$(selector).css(property,value)
... obtient, et se couche. C'est ce que j'utilise, le seul inconvénient est que vous connaissez JQuery, mais c'est honnêtement l'une des très bonnes raisons pour que chaque développeur Javascript apprenne JQuery, cela rend la vie facile et propose des méthodes, comme celle-ci, qui n'est pas disponible avec Javascript standard. J'espère que cela aide quelqu'un !!!
Pour tous ceux qui souhaitent définir la valeur d'une variable imbriquée, voici comment procéder:
const _ = require('lodash'); //import lodash module
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.set(object, 'a[0].b.c', 4);
console.log(object.a[0].b.c);
// => 4
Documentation: https://lodash.com/docs/4.17.15#set
Aussi, documentation si vous souhaitez obtenir une valeur: https://lodash.com/docs/4.17.15#get
Vous devez utiliser JSON.parse
, consultez https://www.w3schools.com/js/js_json_parse.asp
const obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}')
console.log(obj.name)
console.log(obj.age)
const something = { bar: "Foobar!" };
const foo = 'bar';
something[\`${foo}\`];
foo
est déjà une chaîne, `${foo}`
c'est exactement la même chose que foo
. (En outre, votre code semble avoir des barres obliques inverses supplémentaires qui ne lui appartiennent pas. Mais cela serait toujours inutile même si vous