2015-02-06 15 views
28

W kilku miejscach przeczytałem, że kluczową różnicą jest to, że "this jest leksykalnie związany w funkcje strzałek." Wszystko dobrze i dobrze, ale nie wiem, co to znaczy.Co oznacza "to" w funkcjach strzałek w ES6?

Wiem, że to znaczy, że jest unikalny w granicach aparatów określających ciało funkcji, ale nie mogłem ci powiedzieć, jaki jest wynik tego kodu, ponieważ nie mam pojęcia, do czego odnosi się nazwa, chyba że chodzi o odniesienie do samej fatalnej funkcji strzałki .... która nie wydaje się przydatna.

var testFunction =() => { console.log(this) }; 
testFunction(); 
+3

to po prostu rejestruje wartość 'this' z zakresu zawierającego, traktując go jak o zmienna termiczna. – Barmar

+1

To tylko dlatego, że nie musisz robić kludge 'var self = this;', a następnie użyć 'self' w funkcji. – Barmar

+4

W twoim przypadku nie ma kontekstu zamykającego, ani kontekstu globalnego, ani kontekstu modułu, więc "to" jest czymkolwiek w tym przypadku, najprawdopodobniej null lub okno. Innymi słowy, 'this' ma dokładnie taką samą wartość, jak w przypadku dodania' console.log (this) 'przed przypisaniem funkcji. –

Odpowiedz

19

Arrow functions capture the this value of the enclosing context

function Person(){ 
    this.age = 0; 

    setInterval(() => { 
    this.age++; // |this| properly refers to the person object 
    }, 1000); 
} 

var p = new Person(); 

Tak więc, aby odpowiedzieć na to pytanie bezpośrednio, this wewnątrz funkcji strzałki by mieć taką samą wartość, jak to miało miejsce tuż przed funkcja strzałka został przydzielony.

+3

Opóźniona odpowiedź @torazaburo - odpowiedź zależy od miejsca, w którym umieszczono ten fragment kodu w pierwotnym pytaniu. Jeśli był na najwyższym poziomie, 'this' jest obiektem' window', jeśli znajdujemy się w przeglądarce i 'module.exports', jeśli znajdujemy się w środowisku węzłów. Chodzi o to, że funkcja strzałki * nie ma wpływu * na wartość 'this'. – Aerovistae

+2

Komentarz z @dave, "' this' wewnątrz twojej funkcji strzałki ma taką samą wartość jak przed przypisaniem funkcji strzałki '", co ostatecznie sprawiło, że kliknęło dla mnie. – Kevin

1

Mam nadzieję, że ten program kodu da lepszy pomysł. Zasadniczo, "to" w funkcji strzałki jest bieżącą kontekstową wersją "tego". Zobacz kod:

// 'this' in normal function & arrow function 
var this1 = { 
    number: 123, 
    logFunction: function() { console.log(this); }, 
    logArrow:() => console.log(this) 
}; 
this1.logFunction(); // Object { number: 123} 
this1.logArrow(); // Window 
5

W celu przedstawienia dużego obrazu opiszę zarówno wiązanie dynamiczne, jak i leksykalne.

Dynamiczny Nazwa Oprawa

this odnosi się do obiektu metoda jest wywoływana. To jest regularnie czytane zdanie na SO. Ale to wciąż tylko fraza, dość abstrakcyjna. Czy istnieje odpowiedni wzór kodu tego zdania?

Tak jest:

const o = { 
    m() { console.log(this) } 
} 

// the important patterns: applying methods 

o.m(); // logs o 
o["m"](); // logs o 

m to metoda, ponieważ opiera się na this. o.m() lub o["m"]() oznacza m jest stosowane do . Wzory te są tłumaczeniem Javascript na nasze słynne zdanie.

Jest jeszcze inny ważny wzór kod, który należy zwrócić uwagę na:

"use strict"; 

const o = { 
    m() { console.log(this) } 
} 

// m is passed to f as a callback 
function f(m) { m() } 

// another important pattern: passing methods 

f(o.m); // logs undefined 
f(o["m"]); // logs undefined 

Jest bardzo podobny do poprzedniego wzoru, tylko nawias brakuje. Ale konsekwencje są znaczne: Po przejściu m do funkcji f, wyciągasz m z jego obiektu/kontekstu o. To jest wykorzenione teraz i this nic nie mówi (zakłada się tryb ścisły).

leksykalna (lub statyczne) Name Binding

Strzałka funkcje nie mają własnych this/super/arguments wiążące. Oni dziedziczyć ich z zakresem leksykalnym dominującej:

const toString = Object.prototype.toString; 
 

 
const o = { 
 
    foo:() => console.log("window", toString.call(this)), 
 
     
 
    bar() { 
 
    const baz =() => console.log("o", toString.call(this)); 
 
    baz(); 
 
    } 
 
} 
 

 
o.foo() // logs window [object Window] 
 
o.bar() // logs o [object Object]

Oprócz zasięgu globalnym (Window w przeglądarkach) tylko funkcje są w stanie utworzyć zakres w JavaScript (i {} bloków w ES2015).Po wywołaniu funkcji strzałki o.foo nie istnieje żadna funkcja otaczająca, z której baz może dziedziczyć jej this. W konsekwencji przechwytuje wiązanie globalnego zasięgu, które jest związane z obiektem Window.

Gdy baz jest wywoływana przez o.bar funkcja strzałka otoczony o.bar (o.bar tworzy swoją nadrzędną zakres leksykograficznego) i może dziedziczyć o.bar jest this wiążące. o.bar został wywołany na o, a tym samym jego this jest związany z o.

0

Można próbować zrozumieć go, postępując zgodnie z dużo poniżej

// whatever here it is, function or fat arrow or literally object declare 
// in short, a pair of curly braces should be appeared here, eg: 
function f() { 
    // the 'this' here is the 'this' in fat arrow function below, they are 
    // bind together right here 
    // if 'this' is meaningful here, eg. this === awesomeObject is true 
    console.log(this) // [object awesomeObject] 
    let a = (...param) => { 
    // 'this is meaningful here too. 
    console.log(this) // [object awesomeObject] 
} 

tak „to” w funkcji strzałka tłuszcz nie jest związana, oznacza, że ​​nie może zrobić nic wiążą się „to” tu .apply wygrał "t, .call nie będzie, .bind nie będzie. "To" w funkcji strzałki tłuszczu jest związane, gdy zapisujesz tekst kodu w edytorze tekstu. "to" w funkcji tłuszczu strzały ma tutaj dosłowne znaczenie. To, co pisze twój kod tutaj w edytorze tekstu, to, co twoja aplikacja uruchomi w repl. Co to "związane" w arror tłuszczu nigdy się nie zmieni, chyba że zmienisz go w edytorze tekstu. Przepraszam za mój angielski basenie ...

1

Strzałka funkcja this jest skierowany do otaczającego rodzica w ES6, oznacza, że ​​nie ma jak anonimowe zakres funkcji w ES5 ...

To bardzo skuteczny sposób, aby uniknąć przypisania var siebie do tego, który jest powszechnie stosowany w ES5 ...

Spójrz na poniższy przykład przypisanie funkcji wewnątrz obiektu:

var checkThis = { 
    normalFunction: function() { console.log(this); }, 
    arrowFunction:() => console.log(this) 
}; 

checkThis.normalFunction(); //Object {} 
checkThis.arrowFunction(); //Window {external: Object, chrome: Object, document: document, tmpDebug: "", j: 0…}