recorrer objetos objeto literales imprimir eliminar elemento crear buscar array agregar javascript object-literal

imprimir - claves dinámicas para literales de objetos en Javascript



recorrer array de objetos javascript (8)

Ok, estoy trabajando en un proyecto en Nodes, y he encontrado un pequeño problema con las claves en los literales de objetos, tengo la siguiente configuración:

var required = { directories : { this.applicationPath : "Application " + this.application + " does not exists", this.applicationPath + "/configs" : "Application config folder does not exists", this.applicationPath + "/controllers" : "Application controllers folder does not exists", this.applicationPath + "/public" : "Application public folder does not exists", this.applicationPath + "/views" : "Application views folder does not exists" }, files : { this.applicationPath + "/init.js" : "Application init.js file does not exists", this.applicationPath + "/controllers/index.js" : "Application index.js controller file does not exists", this.applicationPath + "/configs/application.js": "Application configs/application.js file does not exists", this.applicationPath + "/configs/server.js" : "Application configs/server.js file does not exists" } }

Ok, muchos de ustedes mirarán esto y pensarán que se ve bien, pero el compilador me sigue diciendo que me falta un : (dos puntos), que no soy, parece que el + o y el . ambos están efectuando el compilador.

Ahora creo (no estoy seguro) que los literales de objeto se crean en tiempo de compilación y no en tiempo de ejecución, lo que significa que variables dinámicas como this.applicationPath y concatenación no estarán disponibles :( :(

¿Cuál es la mejor manera de superar un obstáculo como este sin tener que volver a escribir grandes trozos de código?


En un literal de objeto (ECMA-262 §11.1.5 lo llama un "inicializador de objetos"), la clave debe ser uno de:

  1. IdentifierName
  2. StringLiteral
  3. NumericLiteral

Por lo tanto, no puede usar una expresión como la clave en un inicializador. Puede usar una expresión con notación de corchetes para acceder a una propiedad. Entonces, para establecer las propiedades con una expresión, debe hacer lo siguiente:

var required = { directories : {}}; required.directories[this.applicationPath] = "Application " + this.application + " does not exists"; required.directories[this.applicationPath + "/configs"] = "Application config folder does not exists"; ...

y así. Como this.applicationPath se reutiliza mucho, es mejor almacenar una referencia para ayudar con el rendimiento y reducir la cantidad de código:

var a = this.applicationPath; var required = { directories : {}}; var rd = required.directories; rd[a] = "Application " + this.application + " does not exists"; rd[a + "/configs"] = "Application config folder does not exists"; ...

Editar

A partir de ECMAScript ed 6, los inicializadores de objetos pueden tener claves calculadas usando:

[expression]: value

También hay una sintaxis abreviada para los nombres de propiedades y métodos.

Ver MDN: Object Initializer o ECMAScript §12.2.6 .


Inspirado por cómo babel encubierta la nueva sintaxis de ES6 ( {[expression]: value} ) a Javascript anterior, aprendí que puedes hacerlo con un trazador de líneas:

var obj = (_obj = {}, _obj[expression] = value, _obj);

Ejemplo:

var dynamic_key = "hello"; var value = "world"; var obj = (_obj = {}, _obj[dynamic_key] = value, _obj); console.log(obj); // Object {hello: "world"}

(Probado en el último Chrome)


La única forma en que puede establecer claves dinámicas es con la notación de corchetes:

required.directories[this.applicationPath + "/configs"] = "Application config folder does not exists";

(por supuesto, donde sea que hagas esta definición, this.applicationPath debe existir)

Pero, ¿necesitas esto. this.applicationPath ? ¿ this.applicationPath en las teclas? ¿Cómo accedes a estos valores? Tal vez solo pueda eliminar this.applicationPath del valor que use para acceder a las propiedades.

Pero en caso de que lo necesites:

Puede usar una matriz para inicializar las claves si quiere evitar repetir una gran cantidad de código:

var dirs = [''configs'', ''controllers'', ...]; var files = [''init.js'', ''controllers/index.js'', ...]; var required = { directories: {}, files: {} }; required.directories[this.applicationPath] = "Application " + this.application + " does not exists"; for(var i = dirs.length; i--;) { required.directories[this.applicationPath + ''/'' + dirs[i]] = "Application " + dirs[i] + " folder does not exists"; } for(var i = files.length; i--;) { // same here }



Para los literales de objetos, el script Javascript / ECMAScript especifica que las claves pueden ser un identificador válido, un literal de cadena o un robot de crédito de número (incluso hexadecimal). No es una expresión, que es lo que required.applicationPath + "/configs" is.


Si tiene una estructura de objeto profunda (como Grunt config), a veces es conveniente poder devolver claves de objeto generadas dinámicamente usando la notación de corchetes descrita por , pero en línea dentro de la estructura del objeto. Esto se puede lograr utilizando una función para devolver dinámicamente un objeto dentro del contexto del objeto profundo; en el caso del código en esta pregunta, algo como esto:

var required = { directories : function() { var o = {}; o[this.applicationPath] = "Application " + this.application + " does not exists"; o[this.applicationPath + "/configs"] = "Application config folder does not exists"; o[this.applicationPath + "/controllers"] = "Application controllers folder does not exists"; o[this.applicationPath + "/public"] = "Application public folder does not exists"; o[this.applicationPath + "/views"] = "Application views folder does not exists"; return o; }(), files : function() { var o = {}; o[this.applicationPath + "/init.js"] = "Application init.js file does not exists"; o[this.applicationPath + "/controllers/index.js"] = "Application index.js controller file does not exists"; o[this.applicationPath + "/configs/application.js"] ="Application configs/application.js file does not exists"; o[this.applicationPath + "/configs/server.js"] ="Application configs/server.js file does not exists"; return o; }() }

Este violín valida este enfoque.


Una vieja pregunta, y las respuestas fueron correctas en ese momento, pero los tiempos cambian. En caso de que alguien lo desentierre en una búsqueda en Google, las nuevas versiones de JavaScript (ES6) permiten usar expresiones como claves para los literales de objetos, si están rodeados entre corchetes: var obj={["a"+Math.PI]:42}


el problema es usar ''esto'' porque no se refiere a nada inteligente *. crea el literal estático con el applicationPath en él.

var required={ "applicationPath":"someWhereOverTheRainboW" };

Entonces usa

required.directories={}; required.directories[required.applicationPath + "/configs"]="Application config folder does not exists"; ....

llenarlo dinámicamente

Editar; Corrí con mi primera idea, no funcionó. Lo anterior funciona ahora, ¡lo siento por eso!

* la palabra clave ''this'' es muy inteligente :) pero a menudo se refiere al objeto window o al elemento, el evento se ha activado o el objeto ''activo'' llamado. Por lo tanto, creando mucha confusión;)