Qual é o significado de "=>" (uma seta formada de iguais e maiores que) em JavaScript?

444

Eu sei que o >=operador significa mais que ou igual a, mas já vi =>em algum código-fonte. Qual o significado desse operador?

Aqui está o código:

promiseTargetFile(fpParams, aSkipPrompt, relatedURI).then(aDialogAccepted => {
    if (!aDialogAccepted)
        return;

    saveAsType = fpParams.saveAsType;
    file = fpParams.file;

    continueSave();
}).then(null, Components.utils.reportError);
rpgs_player
fonte
5
Veja este link sobre as funções das setas .
Mistalis

Respostas:

546

O que é isso

Esta é uma função de seta. As funções de seta são uma sintaxe curta, introduzida pelo ECMAscript 6, que pode ser usada de maneira semelhante à maneira como você usaria expressões de função. Em outras palavras, você pode frequentemente usá-los no lugar de expressões como function (foo) {...}. Mas eles têm algumas diferenças importantes. Por exemplo, eles não vinculam seus próprios valores de this(veja a discussão abaixo).

As funções de seta fazem parte da especificação ECMAscript 6. Eles ainda não são suportados em todos os navegadores, mas são parcial ou totalmente suportados no Node v. 4.0+ e na maioria dos navegadores modernos em uso a partir de 2018. (Incluí uma lista parcial dos navegadores de suporte abaixo).

Você pode ler mais na documentação do Mozilla sobre funções de seta .

Na documentação do Mozilla:

Uma expressão função seta (também conhecido como função seta gordura) tem uma sintaxe mais curta em comparação com a expressão de função e lexicamente se liga o thisvalor (não se ligar ao seu próprio this, arguments, super, ou new.target). As funções de seta são sempre anônimas. Essas expressões de função são mais adequadas para funções que não são de método e não podem ser usadas como construtores.

Uma nota sobre como thisfunciona as funções de seta

Um dos recursos mais úteis de uma função de seta está oculto no texto acima:

Uma função de seta ... vincula lexicamente o thisvalor (não vincula o seu próprio this...)

O que isso significa em termos mais simples é que a função de seta retém o thisvalor de seu contexto e não possui o seu próprio this. Uma função tradicional pode vincular seu próprio thisvalor, dependendo de como é definida e chamada. Isso pode exigir muita ginástica self = this;, etc., para acessar ou manipular a thispartir de uma função dentro de outra função. Para mais informações sobre este tópico, consulte a explicação e os exemplos na documentação do Mozilla .

Código de exemplo

Exemplo (também dos documentos):

var a = [
  "We're up all night 'til the sun",
  "We're up all night to get some",
  "We're up all night for good fun",
  "We're up all night to get lucky"
];

// These two assignments are equivalent:

// Old-school:
var a2 = a.map(function(s){ return s.length });

// ECMAscript 6 using arrow functions
var a3 = a.map( s => s.length );

// both a2 and a3 will be equal to [31, 30, 31, 31]

Notas sobre compatibilidade

Você pode usar as funções de seta no Nó, mas o suporte ao navegador é irregular.

O suporte ao navegador para essa funcionalidade melhorou bastante, mas ainda não é amplo o suficiente para a maioria dos usos baseados no navegador. Em 12 de dezembro de 2017, ele é suportado nas versões atuais de:

  • Chrome (v. 45+)
  • Firefox (versão 22 ou superior)
  • Borda (v. 12+)
  • Ópera (v. 32+)
  • Navegador Android (v. 47+)
  • Opera Mobile (versão 33+)
  • Chrome para Android (v. 47+)
  • Firefox para Android (v. 44 ou superior)
  • Safari (versão 10+)
  • Safari para iOS (v. 10.2 ou superior)
  • Internet da Samsung (v. 5+)
  • Navegador Baidu (v. 7.12+)

Não suportado em:

  • IE (através do v. 11)
  • Opera Mini (até a versão 8.0)
  • Navegador Blackberry (até a versão 10)
  • IE Mobile (até a versão 11)
  • Navegador UC para Android (através da v. 11.4)
  • QQ (através da v. 1.2)

Você pode encontrar mais informações (e mais atuais) em CanIUse.com (sem afiliação).

elixenida
fonte
3
O TypeScript também parece suportá-lo.
Mtyson #
1
Parece que esta é uma expressão lambda, sim?
Addem
1
Queria mencionar em termos de compatibilidade do navegador Eu uso as funções de seta ES6 / ES7 e outros recursos não compatíveis com o IE11 nativamente, mas eu uso o Gulp ou Webpack junto com o Babel para transpilar o ES6 para o ES5 para que ele funcione no IE11. Portanto, se você precisar do suporte ao IE11 e não se importa de configurar o Babel, faça isso.
mbokil
76

Isso é conhecido como uma função de seta, parte das especificações do ECMAScript 2015 ...

var foo = ['a', 'ab', 'abc'];

var bar = foo.map(f => f.length);

console.log(bar); // 1,2,3

Sintaxe mais curta que a anterior:

// < ES6:
var foo = ['a', 'ab', 'abc'];

var bar = foo.map(function(f) {
  return f.length;
});
console.log(bar); // 1,2,3

DEMO

A outra coisa impressionante é lexical this ... Normalmente, você faria algo como:

function Foo() {
  this.name = name;
  this.count = 0;
  this.startCounting();
}

Foo.prototype.startCounting = function() {
  var self = this;
  setInterval(function() {
    // this is the Window, not Foo {}, as you might expect
    console.log(this); // [object Window]
    // that's why we reassign this to self before setInterval()
    console.log(self.count);
    self.count++;
  }, 1000)
}

new Foo();

Mas isso pode ser reescrito com a seta assim:

function Foo() {
  this.name = name;
  this.count = 0;
  this.startCounting();
}

Foo.prototype.startCounting = function() {
  setInterval(() => {
    console.log(this); // [object Object]
    console.log(this.count); // 1, 2, 3
    this.count++;
  }, 1000)
}

new Foo();

DEMO

MDN
Mais sobre sintaxe

Para mais, aqui está uma resposta muito boa para quando usar as funções de seta.

brbcoding
fonte
Seria bom para atualizar os demos para uso esfiddle.net como es6fiddle.net não é mais operacional
Wavesailor
25

Essa seria a "expressão da função da seta" introduzida no ECMAScript 6.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions

Para propósitos históricos (se a página da wiki mudar posteriormente), é:

Uma expressão de função de seta possui uma sintaxe mais curta em comparação com as expressões de função e vincula lexicamente o valor this. As funções de seta são sempre anônimas.

Kyle Falconer
fonte
1
Importa incluir informações suficientes para que a maioria dos leitores não precise se aprofundar?
23414 djechlin
2
O wiki ao qual vinculei descreve muito sucintamente o que é: "Uma expressão de função de seta possui uma sintaxe mais curta em comparação com expressões de função e vincula lexicamente esse valor. As funções de seta são sempre anônimas."
Kyle Falconer
1
Adicionar isso como uma citação aqui realmente ajudará sua resposta.
Hanky ​​Panky
22

Estas são as funções de seta

Também conhecido como Fat Arrow Functions . Eles são uma maneira limpa e concisa de escrever expressões de função, por exemplo function() {}.

Seta As funções podem eliminar a necessidade de function, returne {}ao definir funções. Eles são one-liners, semelhantes às expressões Lambda em Java ou Python.

Exemplo sem parâmetros

const queue = ['Dave', 'Sarah', 'Sharon'];
const nextCustomer = () => queue[0];

console.log(nextCustomer()); // 'Dave'

Se várias instruções precisarem ser feitas na mesma Função Seta, você precisará agrupar, neste exemplo, queue[0]entre colchetes {}. Nesse caso, a declaração de retorno não pode ser omitida.

Exemplo com 1 parâmetro

const queue = ['Dave', 'Sarah', 'Sharon'];
const addCustomer = name => {
  queue.push(name);
};

addCustomer('Toby');

console.log(queue); // ['Dave', 'Sarah', 'Sharon', 'Toby']

Você pode omitir {}o acima.

Quando existe um único parâmetro, os colchetes ()ao redor do parâmetro podem ser omitidos.

Exemplo com vários parâmetros

const addNumbers = (x, y) => x + y

console.log(addNumbers(1, 5)); // 6

Um exemplo útil

const fruits = [
    {name: 'Apple', price: 2},
    {name: 'Bananna', price: 3},
    {name: 'Pear', price: 1}
];

Se quiséssemos obter o preço de cada fruta em uma única matriz, no ES5 poderíamos:

fruits.map(function(fruit) {
    return fruit.price;
}); // [2, 3, 1]

No ES6 com as novas funções de seta, podemos tornar isso mais conciso:

fruits.map(fruit => fruit.price); // [2, 3, 1]

Informações adicionais sobre as funções de seta podem ser encontradas aqui .

Compatibilidade do navegador

  • IE: Ainda não suportado
  • Edge: 12+ (Todas as versões)
  • Firefox: 22+
  • Chrome: mais de 45
  • Safari: 10+
  • iOS Safari: 10.2 ou superior
  • Navegador Android: mais de 56

Informações adicionais atualizadas podem ser encontradas na compatibilidade do navegador aqui

Toby Mellor
fonte
21

apenas para adicionar outro exemplo do que um lambda pode fazer sem usar o mapa:

a = 10
b = 2

var mixed = (a,b) => a * b; 
// OR
var mixed = (a,b) => { (any logic); return a * b };

console.log(mixed(a,b)) 
// 20
Bart Calixto
fonte
13

Como outros já disseram, é uma nova sintaxe para criar funções.

No entanto, esse tipo de função difere das normais:

  • Eles vinculam o thisvalor. Conforme explicado pelas especificações ,

    Um ArrowFunction não define ligações locais para arguments, super, this, ou new.target. Qualquer referência a arguments, super, this, ou new.targetdentro de uma ArrowFunction deve ser resolvido para uma ligação em um ambiente lexicamente vedante. Normalmente, este será o ambiente de funções de uma função que encerra imediatamente.

    Mesmo que um ArrowFunction possa conter referências a super, o objeto de função criado na etapa 4 não é transformado em um método executando MakeMethod . Um ArrowFunction que faz referência super sempre está contido em um não- ArrowFunction e o estado necessário para implementar superé acessível através do escopo capturado pelo objeto de função do ArrowFunction .

  • Eles não são construtores.

    Isso significa que eles não têm um método interno e, portanto, não podem ser instanciados, por exemplo

    var f = a => a;
    f(123);  // 123
    new f(); // TypeError: f is not a constructor
Oriol
fonte
8

Eu li, este é um símbolo de Arrow FunctionsemES6

isto

var a2 = a.map(function(s){ return s.length });

usando Arrow Functionpode ser escrito como

var a3 = a.map( s => s.length );

Documentos MDN

Mritunjay
fonte
6

Adicionando exemplo simples de CRUD com Arrowfunction

 //Arrow Function
 var customers   = [
   {
     name: 'Dave',
     contact:'9192631770'
   },
   {
     name: 'Sarah',
     contact:'9192631770'
   },
   {
     name: 'Akhil',
     contact:'9928462656' 
   }],

// No Param READ
 getFirstCustomer = () => { 
   console.log(this);
   return customers[0];
 };
  console.log("First Customer "+JSON.stringify(getFirstCustomer())); // 'Dave' 

   //1 Param SEARCH
  getNthCustomer = index=>{
    if( index>customers.length)
    {
     return  "No such thing";
   }
   else{
       return customers[index];
     } 
  };
  console.log("Nth Customer is " +JSON.stringify(getNthCustomer(1))); 

   //2params ADD
  addCustomer = (name, contact)=> customers.push({
     'name': name,
     'contact':contact
    });
  addCustomer('Hitesh','8888813275');
  console.log("Added Customer "+JSON.stringify(customers)); 

  //2 param UPDATE
  updateCustomerName = (index, newName)=>{customers[index].name= newName};
  updateCustomerName(customers.length-1,"HiteshSahu");
  console.log("Updated Customer "+JSON.stringify(customers));

  //1 param DELETE
  removeCustomer = (customerToRemove) => customers.pop(customerToRemove);
  removeCustomer(getFirstCustomer());
  console.log("Removed Customer "+JSON.stringify(customers)); 
Hitesh Sahu
fonte
4

Insatisfeito com as outras respostas. A resposta mais votada em 2019/3/13 está realmente errada.

A versão resumida curta do que =>significa é que é um atalho para escrever uma função E para vinculá-la à atualthis

const foo = a => a * 2;

É efetivamente um atalho para

const foo = function(a) { return a * 2; }.bind(this);

Você pode ver todas as coisas que foram encurtadas. Não precisávamos function, nem returnnem .bind(this)nem chaves nem parênteses

Um exemplo um pouco mais longo de uma função de seta pode ser

const foo = (width, height) => {
  const area = width * height;
  return area;
};

Mostrando que, se queremos múltiplos argumentos para a função, precisamos de parênteses e se queremos escrever mais do que uma única expressão, precisamos de chaves e um explícito return.

É importante entender a .bindparte e é um grande tópico. Tem a ver com o que thissignifica em JavaScript.

Todas as funções têm um parâmetro implícito chamado this. Como thisé definido ao chamar uma função depende de como essa função é chamada.

Toma

function foo() { console.log(this); }

Se você chamar normalmente

function foo() { console.log(this); }
foo();

this será o objeto global.

Se você estiver no modo estrito

`use strict`;
function foo() { console.log(this); }
foo();

// or

function foo() {
   `use strict`;
   console.log(this);
 }
foo();

Será undefined

Você pode definir thisdiretamente usando callouapply

function foo(msg) { console.log(msg, this); }

const obj1 = {abc: 123}
const obj2 = {def: 456}

foo.call(obj1, 'hello');  // prints Hello {abc: 123}
foo.apply(obj2, ['hi']);  // prints Hi {def: 456}

Você também pode definir thisimplicitamente usando o operador de ponto.

function foo(msg) { console.log(msg, this); }
const obj = {
   abc: 123,
   bar: foo,
}
obj.bar('Hola');  // prints Hola {abc:123, bar: f}

Um problema surge quando você deseja usar uma função como retorno de chamada ou ouvinte. Você cria a classe e deseja atribuir uma função como retorno de chamada que acessa uma instância da classe.

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click', function() {
       console.log(this.name);  // won't work
    }); 
  }
}

O código acima não funcionará porque quando o elemento acionar o evento e chamar a função, o thisvalor não será a instância da classe.

Uma maneira comum de resolver esse problema é usar .bind

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click', function() {
       console.log(this.name); 
    }.bind(this); // <=========== ADDED! ===========
  }
}

Como a sintaxe da seta faz a mesma coisa que podemos escrever

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click',() => {
       console.log(this.name); 
    });
  }
}

bindefetivamente cria uma nova função . Se bindnão existisse, você poderia basicamente fazer o seu próprio como este

function bind(funcitonToBind, valueToUseForThis) {
  return function(...args) {
    functionToBind.call(valueToUseForThis, ...args);
  };
}

No JavaScript antigo, sem o operador de propagação, seria

function bind(funcitonToBind, valueToUseForThis) {
  return function() {
    functionToBind.apply(valueToUseForThis, arguments);
  };
}

A compreensão desse código requer um entendimento dos fechamentos, mas a versão curta bindcria uma nova função que sempre chama a função original com o thisvalor que estava vinculado a ela. A função de seta faz a mesma coisa, pois é um atalho parabind(this)

gman
fonte
2

Como todas as outras respostas já disseram, isso faz parte da sintaxe da função de seta do ES2015. Mais especificamente, não é um operador, é um pontuador token que separa os parâmetros do corpo: ArrowFunction : ArrowParameters => ConciseBody. Por exemplo (params) => { /* body */ }.

JMM
fonte
1

ES6 Funções de seta:

Em javascript, =>é o símbolo de uma expressão de função de seta. Uma expressão de função de seta não tem sua própria thisligação e, portanto, não pode ser usada como uma função construtora. por exemplo:

var words = 'hi from outside object';

let obj = {
  words: 'hi from inside object',
  talk1: () => {console.log(this.words)},
  talk2: function () {console.log(this.words)}
}

obj.talk1();  // doesn't have its own this binding, this === window
obj.talk2();  // does have its own this binding, this is obj

Regras de uso das funções de seta:

  • Se houver exatamente um argumento, você poderá omitir os parênteses do argumento.
  • Se você retornar uma expressão e fizer isso na mesma linha, poderá omitir {}a returninstrução e

Por exemplo:

let times2 = val => val * 2;  
// It is on the same line and returns an expression therefore the {} are ommited and the expression returns implictly
// there also is only one argument, therefore the parentheses around the argument are omitted

console.log(times2(3));

Willem van der Veen
fonte
1

As funções de seta, indicadas pelo símbolo (=>), ajudam a criar funções e métodos anônimos. Isso leva a uma sintaxe mais curta. Por exemplo, abaixo está uma função simples "Adicionar" que retorna a adição de dois números.

function Add(num1 , num2 ){
return num1 + num2;
}

A função acima fica mais curta usando a sintaxe “Seta”, como mostrado abaixo.

insira a descrição da imagem aqui

O código acima tem duas partes, como mostrado no diagrama acima: -

Entrada: - Esta seção especifica os parâmetros de entrada para a função anônima.

Lógica: - Esta seção vem após o símbolo "=>". Esta seção possui a lógica da função real.

Muitos desenvolvedores pensam que a função seta torna sua sintaxe mais curta, mais simples e, portanto, torna seu código legível.

Se você acredita na frase acima, deixe-me garantir que é um mito. Se você pensa por um momento, uma função corretamente escrita com nome é muito legível do que funções criptografadas criadas em uma linha usando um símbolo de seta.

O principal uso da função de seta é garantir que o código seja executado no contexto dos chamadores.

Veja o código abaixo no qual tem uma variável global "contexto" definida, essa variável global é acessada dentro de uma função "SomeOtherMethod" que é chamada de outro método "SomeMethod".

Este "SomeMethod" possui variável local "context". Agora, como "SomeOtherMethod" é chamado de "" SomeMethod ", esperamos que ele exiba" contexto local ", mas exibe" contexto global ".

var context = global context”;

function SomeOtherMethod(){
alert(this.context);
}

function SomeMethod(){
this.context = local context”;
SomeOtherMethod();
}

var instance = new SomeMethod();

Mas se substituir a chamada usando a função Seta, ela exibirá "contexto local".

var context = "global context";

    function SomeMethod(){
        this.context = "local context";
        SomeOtherMethod = () => {
            alert(this.context);
        }
        SomeOtherMethod();
    }
    var instance = new SomeMethod();

Recomendamos que você leia este link ( função Seta em JavaScript ), que explica todos os cenários do contexto javascript e em quais cenários o contexto dos chamadores não é respeitado.

Você também pode ver a demonstração da função Seta com javascript neste vídeo do youtube, que demonstra praticamente o termo Contexto.

Shivprasad Koirala
fonte
0

Como outros já declararam, funções regulares (tradicionais) são usadas thisno objeto que chamou a função (por exemplo, um botão que foi clicado) . Em vez disso, as funções de seta são usadas thisno objeto que define a função.

Considere duas funções quase idênticas:

regular = function() {
  ' Identical Part Here;
}


arrow = () => {
  ' Identical Part Here;
}

O trecho abaixo demonstra a diferença fundamental entre o que thisrepresenta para cada função. A função regular é exibida, [object HTMLButtonElement]enquanto a função de seta é exibida [object Window].

<html>
 <button id="btn1">Regular: `this` comes from "this button"</button>
 <br><br>
 <button id="btn2">Arrow: `this` comes from object that defines the function</button>
 <p id="res"/>

 <script>
  regular = function() {
    document.getElementById("res").innerHTML = this;
  }

  arrow = () => {
    document.getElementById("res").innerHTML = this;
  }

  document.getElementById("btn1").addEventListener("click", regular);
  document.getElementById("btn2").addEventListener("click", arrow);
 </script>
</html>

Aprendiz lento
fonte