Estoy tratando de acceder a una propiedad de un objeto usando un nombre dinámico. es posible?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Estoy tratando de acceder a una propiedad de un objeto usando un nombre dinámico. es posible?
const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"
Respuestas:
Hay dos formas de acceder a las propiedades de un objeto:
something.bar
something['bar']
El valor entre paréntesis puede ser cualquier expresión. Por lo tanto, si el nombre de la propiedad se almacena en una variable, debe usar la notación de paréntesis:
var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected
Esta es mi solución:
function resolve(path, obj) {
return path.split('.').reduce(function(prev, curr) {
return prev ? prev[curr] : null
}, obj || self)
}
Ejemplos de uso:
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 podemos acceder con:
foo.bar
foo[someVar]
ofoo["string"]
Pero solo el segundo caso permite acceder a las propiedades dinámicamente:
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
El siguiente es un ejemplo de ES6 de cómo puede acceder a la propiedad de un objeto utilizando un nombre de propiedad que se ha generado dinámicamente mediante la concatenación de dos cadenas.
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
Esto se llama nombres de propiedades calculadas
Puede lograr esto de muchas maneras diferentes.
let foo = {
bar: 'Hello World'
};
foo.bar;
foo['bar'];
La notación de corchetes es especialmente poderosa ya que le permite acceder a una propiedad basada en una variable:
let foo = {
bar: 'Hello World'
};
let prop = 'bar';
foo[prop];
Esto se puede extender al bucle sobre cada propiedad de un objeto. Esto puede parecer redundante debido a las nuevas construcciones de JavaScript, como para ... de ..., pero ayuda a ilustrar un caso de uso:
let foo = {
bar: 'Hello World',
baz: 'How are you doing?',
last: 'Quite alright'
};
for (let prop in foo.getOwnPropertyNames()) {
console.log(foo[prop]);
}
La notación de punto y paréntesis también funciona como se espera para los objetos anidados:
let foo = {
bar: {
baz: 'Hello World'
}
};
foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;
Desestructuración de objetos
También podríamos considerar la desestructuración de objetos como un medio para acceder a una propiedad en un objeto, pero de la siguiente manera:
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'
Puedes hacerlo así usando Lodash get
_.get(object, 'a[0].b.c');
He tenido en cuenta los comentarios a continuación y acepto. Eval debe ser evitado.
Acceder a las propiedades raíz en el objeto se logra fácilmente con obj[variable]
, pero anidarse complica las cosas. No escribir código ya escrito que sugiero usar lodash.get
.
Ejemplo
// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);
// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);
Lodash get se puede usar de diferentes maneras, aquí hay un enlace a la documentación lodash.get
eval
siempre que sea posible. stackoverflow.com/questions/86513/…
eval
para algo tan trivial como acceder a las propiedades es simplemente excesivo y difícilmente aconsejable bajo ninguna circunstancia. ¿Qué es "problema"? obj['nested']['test']
funciona muy bien y no requiere que incruste código en cadenas.
obj['nested']['value']
- recuerda niños, eval es malvado!
_.get
a la mesa. Creo que esta respuesta merece ahora votos positivos en lugar de votos negativos. Puede ser excesivo, pero es bueno saber que existe.
Siempre que necesite acceder a la propiedad dinámicamente, debe usar corchetes para acceder a la propiedad no ". operador
Sintaxis: objeto [propiedad}
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])
Encontré un caso en el que pensé que quería pasar la "dirección" de una propiedad de objeto como datos a otra función y llenar el objeto (con AJAX), buscar desde la matriz de direcciones y mostrar esa otra función. No podía usar la notación de puntos sin hacer acrobacias de cadena, así que pensé que sería bueno pasar una matriz. Terminé haciendo algo diferente de todos modos, pero parecía relacionado con esta publicación.
Aquí hay una muestra de un objeto de archivo de idioma como el que quería datos:
const locs = {
"audioPlayer": {
"controls": {
"start": "start",
"stop": "stop"
},
"heading": "Use controls to start and stop audio."
}
}
Quería poder pasar una matriz como: ["audioPlayer", "controles", "detener"] para acceder al texto del idioma, "detener" en este caso.
Creé esta pequeña función que busca el parámetro de dirección "menos específico" (primero) y reasigna el objeto devuelto a sí mismo. Entonces está listo para buscar el siguiente parámetro de dirección más específico si existe.
function getText(selectionArray, obj) {
selectionArray.forEach(key => {
obj = obj[key];
});
return obj;
}
uso:
/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs));
/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs));
Se pone interesante cuando tienes que pasar parámetros a esta función también.
Código 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
Este simple código puede verificar la existencia de variables / valores profundamente anidados sin tener que verificar cada variable en el camino ...
var getValue = function( s, context ){
return Function.call( context || null, 'return ' + s )();
}
Ex. - una matriz de objetos profundamente anidada:
a = [
{
b : [
{
a : 1,
b : [
{
c : 1,
d : 2 // we want to check for this
}
]
}
]
}
]
En lugar 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
Ahora podemos:
if( getValue('a[0].b[0].b[0].d') == 2 ) // true
¡Salud!
Hice una pregunta que se duplicó un poco sobre este tema hace un tiempo, y después de una investigación excesiva, y viendo que falta mucha información que debería estar aquí, siento que tengo algo valioso que agregar a esta publicación anterior.
let properyValue = element.style['enter-a-property'];
sin embargo, rara vez tomo esta ruta porque no funciona en valores de propiedad asignados a través de hojas de estilo. Para darle un ejemplo, lo demostraré con un poco de pseudocódigo.
let elem = document.getElementById('someDiv');
let cssProp = elem.style['width'];
Usando el ejemplo de código anterior; si la propiedad de ancho del elemento div que se almacenó en la variable 'elem' se diseñó en una hoja de estilo CSS, y no se diseñó dentro de su etiqueta HTML, sin duda obtendrá un valor de retorno de indefinido almacenado en el interior de la variable cssProp. El valor indefinido ocurre porque para obtener el valor correcto, el código escrito dentro de una hoja de estilo CSS debe calcularse para obtener el valor, por lo tanto; debe usar un método que calcule el valor de la propiedad cuyo valor se encuentra dentro de la hoja de estilo.
function getCssProp(){
let ele = document.getElementById("test");
let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}
W3Schools getComputedValue Doc Esto proporciona un buen ejemplo y le permite jugar con él, sin embargo, este enlace Mozilla CSS getComputedValue doc habla sobre la función getComputedValue en detalle, y debe ser leído por cualquier desarrollador aspirante que no esté totalmente claro sobre este tema.
$(selector).css(property,value)
... consigue y establece. Es lo que uso, el único inconveniente es que debes conocer JQuery, pero esta es honestamente una de las muchas buenas razones por las que todo desarrollador de Javascript debería aprender JQuery, simplemente hace la vida más fácil y ofrece métodos, como este, que no está disponible con Javascript estándar. ¡¡¡Espero que esto ayude a alguien!!!
Para cualquiera que busque establecer el valor de una variable anidada, aquí se explica cómo hacerlo:
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
Documentación: https://lodash.com/docs/4.17.15#set
Además, documentación si desea obtener un valor: https://lodash.com/docs/4.17.15#get
Debe usar JSON.parse
, eche un vistazo a 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
ya es una cadena, por lo que `${foo}`
es exactamente lo mismo que foo
. (Además, el código parece tener algunas barras invertidas adicionales que no pertenecen allí Pero aún sería inútil incluso si se fija que error de sintaxis..)