2015-02-06 8 views
28

Ho letto in diversi punti che la differenza chiave è che "this è legato lessicamente alle funzioni di freccia". Va tutto bene, ma in realtà non so cosa significhi.A cosa si riferisce "questo" nelle funzioni freccia in ES6?

so che significa che è unico nel suo genere all'interno dei confini dei supporti che definiscono il corpo della funzione, ma non ho potuto davvero dire l'output del seguente codice, perché non ho idea di cosa this si riferisce, a meno che non si tratta di riferimento alla stessa funzione della freccia grossa .... che non sembra utile.

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

cattura semplicemente il valore di 'this' dall'ambito contenente, trattandolo come qualsiasi o c'è una variabile. – Barmar

+1

E 'solo così non devi fare il kludge di 'var self = this;' e quindi usare' self' nella funzione. – Barmar

+4

Nel tuo caso, non esiste un contesto che lo racchiude, o è il contesto globale, o il contesto del modulo, quindi "questo" è qualunque cosa sia in quel caso, molto probabilmente null o window. Per dirla in altro modo, "questo" ha esattamente lo stesso valore che avrebbe se avessi aggiunto un "console.log (questo)" prima dell'assegnazione della funzione. –

risposta

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

Quindi, per rispondere alla tua domanda direttamente, this all'interno della vostra funzione freccia avrebbe lo stesso valore come ha fatto a destra prima è stata assegnata la funzione freccia.

+3

risposta ritardata @torazaburo - la risposta dipende da dove è stato inserito lo snippet di codice nella domanda originale. Se era al livello più alto, 'this' è l'oggetto' window' se siamo in un browser e 'module.exports' se siamo in un ambiente Node. Il punto è che la funzione freccia * non ha effetto * sul valore di 'this'. – Aerovistae

+2

Il commento da @dave, "questo" all'interno della funzione della freccia avrebbe lo stesso valore che aveva prima che fosse assegnata la funzione della freccia "è ciò che finalmente ha fatto clic per me. – Kevin

1

Spero che questo codice mostra un'idea più chiara. Fondamentalmente, 'this' in arrow function è la versione di contesto corrente di 'this'. Vedere il codice:

// '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

Per fornire il quadro generale, spiegherò il binding sia dinamico che lessicale.

Nome dinamica Binding

this riferisce all'oggetto il metodo viene chiamato. Questa è una frase da leggere regolarmente su SO. Ma è ancora solo una frase, piuttosto astratta. C'è un modello di codice corrispondente a questa frase?

sì, c'è:

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

// the important patterns: applying methods 

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

m è un metodo perché si basa su this. o.m() o o["m"]() significa che m si applica a o. Questi modelli sono la traduzione Javascript della nostra famosa frase.

c'è un altro modello di codice importante che si dovrebbe prestare attenzione a:

"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 

E 'molto simile al modello precedente, solo la parentesi sono mancanti. Ma le conseguenze sono considerevoli: quando si passa m alla funzione f, si estrae m dell'oggetto/contesto o. Ora viene sradicato e this non fa riferimento a nulla (modalità rigorosa).

lessicale (o statico) Nome Binding

funzioni freccia non hanno un proprio this/super/arguments vincolante. Li ereditano da loro genitore scope lessicale:

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]

A parte l'ambito globale (Window nei browser) solo funzioni sono in grado di formare un ambito in Javascript (e {} blocchi nel ES2015).Quando viene chiamata la funzione di freccia o.foo, non esiste alcuna funzione circostante da cui baz possa ereditare il proprio this. Di conseguenza, acquisisce il binding this dell'ambito globale associato all'oggetto Window.

Quando baz viene richiamato dal o.bar, la funzione freccia è circondato da o.bar (o.bar forma suo genitore scope lessicale) e possono ereditare o.bar s' this vincolante. o.bar è stato chiamato su o e pertanto il suo this è associato a o.

0

Si può cercare di capire seguendo la strada sotto di

// 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] 
} 

cosi 'questo' nella funzione freccia grasso non è vincolata, significa che non si può fare qualsiasi cosa si legano a 'questo' qui, ha vinto .Applicare 't, .call non lo farà, .bind non lo farà. 'questa funzione' in fat arrow è vincolata quando si scrive il testo del codice nell'editor di testo. 'questo' in funzione freccia grossa è letteralmente significativo qui. Ciò che il tuo codice scrive qui nell'editor di testo è ciò che la tua app esegue in repl. Ciò che questo "presente" associato all'arresto di grasso non cambierà mai a meno che non lo si cambi nell'editor di testo. Scusate per la mia piscina inglese ...

funzione
1

Freccia this sta indicando al genitore circostante ES6, significa che non è così portata come funzioni anonime in ES5 ...

è modo molto utile per evitare di assegnare var sé a questo che è ampiamente usato in ES5 ...

Osservare l'esempio seguente, assegnando una funzione all'interno di un oggetto:

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…}