ES6 getter / setter com função de seta

100

Estou usando o babel6 e para meu projeto de estimação estou criando um wrapper para XMLHttpRequest, para os métodos que posso usar:

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

mas para a função de seta de propriedades não funciona

isso funciona:

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

mas eu não posso usar

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

Isso é intencional?

Gabor Dolla
fonte
Você não precisa das chaves ou do retorno; você pode apenas dizer (method, url, something) => this.xhr.open(method. url, something).
geté uma parte de um literal de objeto ou de uma definição de classe, uma atribuição de variável não. Por que você acha que eles deveriam funcionar da mesma forma?
Bergi de
1
status => this.xhr.status(sintaxe c # 7) ou talvez get status() => this.xhr.statusfosse realmente um ótimo açúcar sintático para legibilidade, mas o Javascript e não o Typescript (ainda?) não o suporta
Charles HETIER

Respostas:

109

De acordo com a gramática ES2015, uma propriedade em um objeto literal pode ser apenas uma de quatro coisas:

PropertyDefinition :

  • IdentifierReference
  • PropertyName : AssignmentExpression
  • MethodDefinition

O único desse tipo que permite uma liderança geté MethodDefinition :

Definição do Método :

  • PropertyName ( StrictFormalParameters ) { FunctionBody }
  • GeneratorMethod
  • get PropertyName ( ) { FunctionBody }
  • set PropertyName ( PropertySetParameterList ) { FunctionBody }

Como você pode ver, a getforma segue uma gramática muito limitada que deve ser da mesma forma

get NAME () { BODY }

A gramática não permite funções da forma get NAME = ....

Apsillers
fonte
Obrigado pela ajuda, aceito sua resposta. Você sabe onde está definido que getter / setter não pode ser usado com uma atribuição? Apenas curioso.
Gabor Dolla de
@GaborDolla Editado para se referir à gramática literal do objeto na especificação ECMAScript.
apsillers de
35

A resposta aceita é ótima. É melhor se você estiver disposto a usar a sintaxe de função normal em vez da "sintaxe de função de seta" compacta.

Mas talvez você realmente goste das funções de seta; talvez você use a função de seta por outro motivo que uma sintaxe de função normal não pode substituir ; você pode precisar de uma solução diferente.

Por exemplo, noto que o OP usa this, você pode querer vincularthis lexicamente; também conhecido como "não vinculativo deste" ), e as funções de seta são boas para esse vínculo léxico.

Você ainda pode usar uma função de seta com um getter por meio da Object.definePropertytécnica.

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

Veja menções de object initializationtécnica (aka get NAME() {...}) vs a definePropertytécnica (aka get : ()=>{}) . Há pelo menos uma diferença significativa, o uso definePropertyrequer as variáveis ​​já existentes:

Definindo um getter em objetos existentes

ou seja, com Object.definePropertyvocê deve garantir que your_obj(no meu exemplo) existe e é salvo em uma variável (enquanto com um object-initializationvocê poderia retornar um objeto-literal na inicialização do objeto:) {..., get(){ }, ... }. Mais informações Object.definePropertyespecificamente aqui

Object.defineProperty(...)parece ter suporte de navegador comparável à get NAME(){...}sintaxe; navegadores modernos, IE 9.

The Red Pea
fonte
10
Inteligente, mas no final das contas é muito mais detalhado do que apenas:get status() { return this.xhr.status; }
devuxer
2
@devuxer Concordo que é muito prolixo. Mas, só para ficar claro, você this deve ser o objeto em que get status() { ... }está definido. Mas meu this poderia ser outra coisa, devido a diferenças de ligação lexical, certo?
The Red Pea
2
Concordo ... embora na prática, eu não tenha encontrado um caso em thisque não seja o que eu quero em um acessor get. (Os thisbenefícios de ligação das funções de seta parecem entrar em
ação
3
Eu concordo, eu freqüentemente uso flecha gorda + ligações lexicais ()=>{}para os callbacks que eu passo para uma promessa , como $http(...).then((promise_result)=> this...})). Se eu não usar flecha gorda, thisrepresentará o Windowobjeto global ; não é muito útil. Mas eu raramente (nunca?) Usei ()=>{}como função para um "get accessor" como você diz ... pelo menos thisdentro de get()representará o objeto no qual get()está definido (que já é mais útil do que Window; portanto, não há necessidade de usar uma função de seta gorda!)
The Red Pea