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?


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 = ....


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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.