Autorreferencias en literales/inicializadores de objetos
¿Hay alguna manera de hacer que algo como lo siguiente funcione en JavaScript?
var foo = {
a: 5,
b: 6,
c: this.a + this.b // Doesn't work
};
En el formato actual, este código obviamente arroja un error de referencia ya que this
no hace referencia a foo
. Pero, ¿ hay alguna forma de que los valores de las propiedades de un objeto literal dependan de otras propiedades declaradas anteriormente?
Bueno, lo único que puedo contarte es getter :
var foo = {
a: 5,
b: 6,
get c() {
return this.a + this.b;
}
}
console.log(foo.c) // 11
Esta es una extensión sintáctica introducida por la especificación ECMAScript 5.ª edición, la sintaxis es compatible con la mayoría de los navegadores modernos (incluido IE9).
Podrías hacer algo como:
var foo = {
a: 5,
b: 6,
init: function() {
this.c = this.a + this.b;
return this;
}
}.init();
Esto sería una especie de inicialización única del objeto.
Tenga en cuenta que en realidad está asignando el valor de retorno de init()
a foo
, por lo tanto debe hacerlo return this
.
Falta la respuesta obvia y simple, así que para completar:
Pero, ¿ hay alguna forma de que los valores de las propiedades de un objeto literal dependan de otras propiedades declaradas anteriormente?
No. Todas las soluciones aquí lo difieren hasta que se crea el objeto (de varias maneras) y luego asignan la tercera propiedad. La forma más sencilla es hacer esto:
var foo = {
a: 5,
b: 6
};
foo.c = foo.a + foo.b;
Todos los demás son simplemente formas más indirectas de hacer lo mismo. (Felix es particularmente inteligente, pero requiere crear y destruir una función temporal, lo que agrega complejidad; y deja una propiedad adicional en el objeto o [si tiene delete
esa propiedad] afecta el rendimiento de los accesos posteriores a la propiedad en ese objeto).
Si necesita que todo esté dentro de una expresión, puede hacerlo sin la propiedad temporal:
var foo = function(o) {
o.c = o.a + o.b;
return o;
}({a: 5, b: 6});
O por supuesto, si necesitas hacer esto más de una vez:
function buildFoo(a, b) {
var o = {a: a, b: b};
o.c = o.a + o.b;
return o;
}
luego donde necesitas usarlo:
var foo = buildFoo(5, 6);