Co oznacza „=>” (strzałka utworzona z równych i większych niż) w JavaScript?


444

Wiem, że >=operator oznacza więcej lub więcej, ale widziałem =>w jakimś kodzie źródłowym. Jakie jest znaczenie tego operatora?

Oto kod:

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

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

    continueSave();
}).then(null, Components.utils.reportError);

5
Zobacz ten link na temat funkcji strzałek .
Mistalis,

Odpowiedzi:


546

Co to jest

To jest funkcja strzałki. Funkcje strzałek to krótka składnia wprowadzona przez ECMAscript 6, której można używać podobnie jak w wyrażeniach funkcyjnych. Innymi słowy, często możesz ich używać zamiast wyrażeń takich jak function (foo) {...}. Ale mają kilka ważnych różnic. Na przykład nie wiążą własnych wartości this(patrz dyskusja poniżej).

Funkcje strzałek są częścią specyfikacji ECMAscript 6. Nie są jeszcze obsługiwane we wszystkich przeglądarkach, ale są częściowo lub w pełni obsługiwane w Node v. 4.0+ i w większości nowoczesnych przeglądarek używanych od 2018 r. (Poniżej zamieszczam częściową listę obsługiwanych przeglądarek).

Możesz przeczytać więcej w dokumentacji Mozilli na temat funkcji strzałek .

Z dokumentacji Mozilli:

Wyrażenie funkcja strzałka (znany również jako funkcja strzałki tłuszczu) ma krótszy składni porównaniu do ekspresji funkcji i lexically wiąże thiswartość (nie wiąże własny this, arguments, super, i new.target). Funkcje strzałek są zawsze anonimowe. Te wyrażenia funkcyjne najlepiej nadają się do funkcji niemetodowych i nie można ich używać jako konstruktorów.

Uwaga na temat thisdziałania funkcji strzałek

Jedna z najbardziej przydatnych funkcji funkcji strzałki jest ukryta w powyższym tekście:

Funkcja strzałki ... leksykalnie wiąże thiswartość (nie wiąże własnej this...)

Mówiąc prościej, oznacza to, że funkcja strzałki zachowuje thiswartość z kontekstu i nie ma własnej wartości this. Tradycyjna funkcja może powiązać własną thiswartość, w zależności od tego, jak zostanie zdefiniowana i wywołana. Może to wymagać wielu ćwiczeń gimnastycznych, takich jak self = this;itp., Aby uzyskać dostęp do thisjednej funkcji w innej funkcji lub manipulować nią . Aby uzyskać więcej informacji na ten temat, zobacz wyjaśnienie i przykłady w dokumentacji Mozilli .

Przykładowy kod

Przykład (również z dokumentów):

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]

Uwagi na temat zgodności

Możesz używać funkcji strzałek w Węźle, ale obsługa przeglądarki jest nierówna.

Obsługa tej funkcji znacznie się poprawiła, ale wciąż nie jest wystarczająco rozpowszechniona w przypadku większości zastosowań opartych na przeglądarce. Od 12 grudnia 2017 r. Jest obsługiwany w bieżących wersjach:

  • Chrome (w. 45+)
  • Firefox (w. 22+)
  • Edge (w. 12+)
  • Opera (w. 32+)
  • Przeglądarka Android (w. 47+)
  • Opera Mobile (w. 33+)
  • Chrome na Androida (w. 47+)
  • Firefox na Androida (wer. 44+)
  • Safari (w. 10+)
  • iOS Safari (wer. 10.2+)
  • Samsung Internet (w. 5+)
  • Baidu Browser (w. 7.12+)

Nieobsługiwany w:

  • IE (przez wer. 11)
  • Opera Mini (do wersji 8.0)
  • Przeglądarka Blackberry (do w. 10)
  • IE Mobile (przez wer. 11)
  • Przeglądarka UC dla systemu Android (przez wer. 11.4)
  • QQ (do wersji 1.2)

Więcej (i więcej aktualnych) informacji można znaleźć na CanIUse.com (bez powiązania).


3
Wygląda na to, że TypeScript również go obsługuje.
mtyson

1
Wygląda na to, że to wyrażenie lambda, tak?
Addem

1
Chciałem wspomnieć o kompatybilności przeglądarki. Używam natywnie ES6 / ES7 i innych funkcji niekompatybilnych z IE11, ale używam Gulp lub Webpack wraz z Babel do transponowania ES6 na ES5, więc działa w IE11. Więc jeśli potrzebujesz wsparcia IE11 i nie przeszkadza ci skonfigurowanie Babel, skorzystaj z niego.
mbokil

76

Jest to znane jako funkcja strzałki, część specyfikacji ECMAScript 2015 ...

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

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

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

Krótsza składnia niż poprzednia:

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

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

PRÓBNY

Inną niesamowitą rzeczą jest leksykalna this ... Zazwyczaj robiłbyś coś takiego:

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();

Ale można to przepisać za pomocą strzałki:

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();

PRÓBNY

MDN
Więcej na temat składni

Aby uzyskać więcej, oto całkiem dobra odpowiedź na pytanie, kiedy używać funkcji strzałek.


Dobrze byłoby zaktualizować wersje demo, aby używać esfiddle.net, ponieważ es6fiddle.net nie działa już
Wavesailor,

25

Byłoby to „wyrażenie funkcji strzałki” wprowadzone w ECMAScript 6.

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

Dla celów historycznych (jeśli strona wiki zmieni się później), jest to:

Wyrażenie funkcji strzałki ma krótszą składnię w porównaniu do wyrażeń funkcji i leksykalnie wiąże tę wartość. Funkcje strzałek są zawsze anonimowe.


1
masz dość informacji, aby większość czytelników nie musiała drążyć szczegółów?
djechlin

2
Wiki, do którego podłączyłem, bardzo zwięźle opisuje, co to jest: „Wyrażenie funkcji strzałki ma krótszą składnię w porównaniu do wyrażeń funkcji i leksykalnie wiąże tę wartość. Funkcje strzałki są zawsze anonimowe”.
Kyle Falconer,

1
Dodanie tego jako cytatu naprawdę pomoże w udzieleniu odpowiedzi.
Hanky ​​Panky

22

Są to funkcje strzałek

Znany również jako Funkcje Fat Arrow . Są czystym i spójnym sposobem pisania wyrażeń funkcyjnych, np function() {}.

Funkcje strzałek można usunąć potrzebę function, returna {}przy definiowaniu funkcji. Są one jednowierszowe, podobne do wyrażeń Lambda w Javie lub Pythonie.

Przykład bez parametrów

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

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

Jeśli konieczne jest wykonanie wielu instrukcji w ramach tej samej funkcji strzałki, w tym przykładzie należy owinąć queue[0]nawiasy klamrowe {}. W takim przypadku instrukcja return nie może zostać pominięta.

Przykład z 1 parametrem

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

addCustomer('Toby');

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

Możesz pominąć {}powyższe.

Gdy występuje pojedynczy parametr, nawiasy ()wokół parametru można pominąć.

Przykład z wieloma parametrami

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

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

Przydatny przykład

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

Gdybyśmy chcieli uzyskać cenę każdego owocu w jednej tablicy, w ES5 moglibyśmy zrobić:

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

W ES6 dzięki nowym funkcjom strzałek możemy uczynić to bardziej zwięzłym:

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

Dodatkowe informacje na temat funkcji strzałek można znaleźć tutaj .

Kompatybilność z przeglądarkami

  • IE: Jeszcze nieobsługiwany
  • Edge: 12+ (wszystkie wersje)
  • Firefox: 22+
  • Chrome: 45+
  • Safari: 10+
  • iOS Safari: 10.2+
  • Przeglądarka Android: 56+

Dodatkowe aktualne informacje można znaleźć na temat zgodności przeglądarki tutaj


21

aby dodać kolejny przykład tego, co lambda może zrobić bez użycia mapy:

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

13

Jak powiedzieli inni, jest to nowa składnia do tworzenia funkcji.

Jednak tego rodzaju funkcje różnią się od normalnych:

  • Wiążą thiswartość. Jak wyjaśniono w specyfikacji ,

    ArrowFunction nie definiuje lokalne powiązania dla arguments, super, this, lub new.target. Wszelkie odniesienia do arguments, super, this, lub new.targetw ramach ArrowFunction musi rozwiązać do wiązania w środowisku leksykalnie osłaniającego. Zazwyczaj będzie to środowisko funkcyjne funkcji natychmiast zamykającej.

    Chociaż funkcja ArrowFunction może zawierać odniesienia do super, obiekt funkcji utworzony w kroku 4 nie jest przekształcany w metodę przez wykonanie metody MakeMethod . Funkcja ArrowFunction, która odwołuje się, super jest zawsze zawarta w funkcji innej niż ArrowFunction, a stan konieczny do wdrożenia superjest dostępny za pośrednictwem zakresu przechwytywanego przez obiekt funkcji ArrowFunction .

  • Nie są konstruktorami.

    Oznacza to, że nie mają metody [[Construct]] i dlatego nie można ich utworzyć, np

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

8

Czytałem, to jest symbol Arrow Functions wES6

to

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

za pomocą Arrow Functionmożna zapisać jako

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

Dokumenty MDN


6

Dodanie prostego przykładu CRUD za pomocą 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)); 

4

Niezadowolony z innych odpowiedzi. Najczęściej głosowana odpowiedź na dzień 2019/3/13 jest nieprawdziwa.

Krótka wersja tego, co =>oznacza, jest skrótem piszącym funkcję ORAZ do wiązania jej z bieżącymthis

const foo = a => a * 2;

Jest skutecznie skrótem do

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

Możesz zobaczyć wszystkie rzeczy, które zostały skrócone. My nie potrzebujemy function, ani returnteż nie.bind(this) ani nawet szelki lub nawiasy

Nieco dłuższy przykład funkcji strzałki może być

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

Pokazując, że jeśli chcemy wielu argumentów funkcji, potrzebujemy nawiasów, a jeśli chcemy zapisać więcej niż jedno wyrażenie, potrzebujemy nawiasów klamrowych i jawnych return.

Ważne jest, aby zrozumieć tę .bindczęść i jest to duży temat. Ma to związek z tym, co thisoznacza JavaScript.

WSZYSTKIE funkcje mają niejawny parametr o nazwie this. Sposób thisustawiania podczas wywoływania funkcji zależy od sposobu jej wywołania.

Brać

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

Jeśli zadzwonisz normalnie

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

this będzie obiektem globalnym.

Jeśli jesteś w trybie ścisłym

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

// or

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

To będzie undefined

Możesz ustawić thisbezpośrednio za pomocą calllubapply

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}

Możesz także ustawić thisdomyślnie za pomocą operatora kropki.

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

Pojawia się problem, gdy chcesz użyć funkcji jako wywołania zwrotnego lub detektora. Tworzysz klasę i chcesz przypisać funkcję jako wywołanie zwrotne, które uzyskuje dostęp do instancji klasy.

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

Powyższy kod nie będzie działał, ponieważ gdy element uruchamia zdarzenie i wywołuje funkcję, thiswartość nie będzie instancją klasy.

Jednym z powszechnych sposobów rozwiązania tego problemu jest użycie .bind

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

Ponieważ składnia strzały robi to samo, co możemy napisać

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

bindskutecznie tworzy nową funkcję . Gdyby bindnie istniał, można w zasadzie stworzyć taki własny

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

W starszym JavaScript bez operatora rozprzestrzeniania byłoby to

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

Zrozumienie tego kodu wymaga zrozumienia zamknięć, ale krótka wersja stanowi bindnową funkcję, która zawsze wywołuje funkcję oryginalną z thiswartością, która była z nią związana. Funkcja strzałki robi to samo, ponieważ są skrótem dobind(this)


2

Jak już wspomniano wszystkie pozostałe odpowiedzi, jest to część składni funkcji strzałek ES2015. Bardziej szczegółowo, nie jest operator, to punctuator token oddziela parametrów z organizmu: ArrowFunction : ArrowParameters => ConciseBody. Np (params) => { /* body */ }.


1

ES6 Funkcje strzałek:

W javascript =>jest to symbol wyrażenia funkcji strzałki. Wyrażenie funkcji strzałki nie ma własnego thiswiązania i dlatego nie może być użyte jako funkcja konstruktora. na przykład:

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

Zasady korzystania z funkcji strzałek:

  • Jeśli istnieje dokładnie jeden argument, możesz pominąć jego nawiasy.
  • Jeśli zwróci wyrażenie i zrobić to na tej samej linii można pominąć {}, a returnoświadczenie

Na przykład:

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));


1

Funkcje strzałek oznaczone symbolem (=>) pomagają tworzyć anonimowe funkcje i metody. To prowadzi do krótszej składni. Na przykład poniżej znajduje się prosta funkcja „Dodaj”, która zwraca dodanie dwóch liczb.

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

Powyższa funkcja staje się krótsza przy użyciu składni „Arrow”, jak pokazano poniżej.

wprowadź opis zdjęcia tutaj

Powyższy kod składa się z dwóch części, jak pokazano na powyższym schemacie:

Dane wejściowe: - Ta sekcja określa parametry wejściowe funkcji anonimowej.

Logika: - Ta sekcja występuje po symbolu „=>”. Ta sekcja ma logikę rzeczywistej funkcji.

Wielu programistów uważa, że ​​funkcja strzałki sprawia, że ​​twoja składnia jest krótsza, prostsza, a tym samym twój kod jest czytelny.

Jeśli wierzysz w powyższe zdanie, to zapewniam cię, że to mit. Jeśli przez chwilę myślisz, że poprawnie napisana funkcja o nazwie jest znacznie czytelniejsza niż funkcje tajemnicze utworzone w jednym wierszu za pomocą symbolu strzałki.

Głównym zastosowaniem funkcji strzałki jest zapewnienie, że kod działa w kontekście wywołującego.

Zobacz poniższy kod, w którym zdefiniowano zmienną globalną „kontekst”. Dostęp do tej zmiennej globalnej można uzyskać w funkcji „SomeOtherMethod”, która jest wywoływana z innej metody „SomeMethod”.

Ta „SomeMethod” ma lokalną zmienną „kontekst”. Ponieważ „SomeOtherMethod” jest wywoływany z „SomeMethod”, spodziewamy się, że wyświetli „kontekst lokalny”, ale wyświetla „kontekst globalny”.

var context = global context”;

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

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

var instance = new SomeMethod();

Ale jeśli zastąpisz połączenie za pomocą funkcji strzałki, wyświetli się „kontekst lokalny”.

var context = "global context";

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

Zachęcam do przeczytania tego linku ( funkcja strzałki w JavaScript ), który wyjaśnia wszystkie scenariusze kontekstu javascript i w których scenariuszach kontekst dzwoniącego nie jest przestrzegany.

Demonstracja funkcji strzałki z javascript w tym filmie na youtube pokazuje praktycznie termin Kontekst.


0

Jak powiedzieli inni, zwykłe (tradycyjne) funkcje korzystają thisz obiektu, który wywołał funkcję (np. Kliknięty przycisk) . Zamiast tego funkcje strzałek używają thisobiektu definiującego funkcję.

Rozważ dwie prawie identyczne funkcje:

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


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

Poniższy fragment thiskodu pokazuje podstawową różnicę między tym, co reprezentuje każdą funkcję. W zwykłej funkcji wyjścia [object HTMLButtonElement]Zważywszy, że funkcja strzałka wyjść [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>

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.