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 return
też 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ę .bind
część i jest to duży temat. Ma to związek z tym, co this
oznacza JavaScript.
WSZYSTKIE funkcje mają niejawny parametr o nazwie this
. Sposób this
ustawiania 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ć this
bezpośrednio za pomocą call
lubapply
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ć this
domyś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ę, this
wartość 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);
});
}
}
bind
skutecznie tworzy nową funkcję . Gdyby bind
nie 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 bind
nową funkcję, która zawsze wywołuje funkcję oryginalną z this
wartością, która była z nią związana. Funkcja strzałki robi to samo, ponieważ są skrótem dobind(this)