Getter / setter ES6 con función de flecha

100

Estoy usando babel6 y para mi proyecto favorito estoy creando un contenedor para XMLHttpRequest, para los métodos que puedo usar:

open = (method, url, something) => {
  return this.xhr.open(method, url, something);
}

pero para las propiedades la función de flecha no funciona

esto funciona:

get status() { return this.xhr.status; }

pero no puedo usar

get status = () => this.xhr.status;

¿Es esto intencional?

Gabor Dolla
fuente
No necesita las llaves ni la devolución; puedes simplemente decir (method, url, something) => this.xhr.open(method. url, something).
getes parte de un objeto literal o una definición de clase, una asignación de variable no lo es. ¿Por qué crees que deberían funcionar igual?
Bergi
1
status => this.xhr.status(sintaxis c # 7) o tal vez get status() => this.xhr.statushubiera sido un gran azúcar sintáctico para la legibilidad, pero Javascript no Typecript no lo admite (¿todavía?)
Charles HETIER

Respuestas:

109

Según la gramática de ES2015, una propiedad en un objeto literal solo puede ser una de cuatro cosas:

PropiedadDefinición :

  • Identificador de referencia
  • PropertyName : AssignmentExpression
  • Método Definición

El único de estos tipos que permite un liderazgo getes MethodDefinition :

Método Definición :

  • PropertyName ( StrictFormalParameters ) { FunctionBody }
  • Método generador
  • get PropertyName ( ) { FunctionBody }
  • set PropertyName ( PropertySetParameterList ) { FunctionBody }

Como puede ver, la getforma sigue una gramática muy limitada que debe ser de la forma

get NAME () { BODY }

La gramática no permite funciones de la forma get NAME = ....

apsillers
fuente
Gracias por tu ayuda, acepto tu respuesta. ¿Sabes dónde está definido que el getter / setter no se puede usar con una asignación? Sólo curioso.
Gabor Dolla
@GaborDolla Editado para hacer referencia a la gramática literal del objeto en la especificación ECMAScript.
apsillers
35

La respuesta aceptada es genial. Es mejor si está dispuesto a utilizar la sintaxis de función normal en lugar de la "sintaxis de función de flecha" compacta.

Pero tal vez te gusten mucho las funciones de flecha; tal vez use la función de flecha por otra razón que una sintaxis de función normal no puede reemplazar ; puede que necesite una solución diferente.

Por ejemplo, noto que OP usa this, es posible que desee enlazar thisléxicamente; también conocido como "no vinculante de esto" ), y las funciones de flecha son buenas para ese vínculo léxico.

Todavía puede usar una función de flecha con un captador a través de la Object.definePropertytécnica.

{
  ...
  Object.defineProperty(your_obj, 'status', { 
     get : () => this.xhr.status 
  });
  ...
}

Ver menciones de object initializationtécnica (alias get NAME() {...}) vs definePropertytécnica (alias get : ()=>{}) . Hay al menos una diferencia significativa, el uso definePropertyrequiere que las variables ya existan:

Definición de un captador en objetos existentes

es decir, con Object.definePropertydebe asegurarse de que your_obj(en mi ejemplo) exista y se guarde en una variable (mientras que con a object-initializationpodría devolver un objeto-literal en la inicialización de su objeto :) {..., get(){ }, ... }. Más información sobre Object.definePropertyespecíficamente, aquí

Object.defineProperty(...)parece tener un soporte de navegador comparable a la get NAME(){...}sintaxis; navegadores modernos, IE 9.

El guisante rojo
fuente
10
Inteligente, pero en última instancia es mucho más detallado que solo:get status() { return this.xhr.status; }
devuxer
2
@devuxer Estoy de acuerdo en que es demasiado detallado. Pero para que quede claro, tu this debe ser el objeto en el que get status() { ... }se define tu. Pero mi this podría ser otra cosa, debido a diferencias léxicas vinculantes, ¿verdad?
The Red Pea
2
De acuerdo ... aunque en la práctica, no me he encontrado con un caso en el thisque no sea lo que quiero en un acceso de obtención. (Los thisbeneficios vinculantes de las funciones de flecha parecen entrar en juego cuando se pasan las funciones, como con los controladores de eventos y las devoluciones de llamada.)
devuxer
3
Estoy de acuerdo, con frecuencia uso la flecha gruesa + enlaces léxicos ()=>{}para las devoluciones de llamada que paso a una Promesa , como $http(...).then((promise_result)=> this...})). Si no utilizo fat-arrow, thisrepresentará el Windowobjeto global ; no muy útil. Pero rara vez (¿nunca?) He usado ()=>{}como función para un "obtener acceso" como usted dice ... al menos thisdentro de get()representará el objeto en el que get()está definido (que ya es más útil que Window; por lo que no hay necesidad de usar una función de flecha gorda!)
The Red Pea