2015-03-01 18 views
8

sto provando ES6 e si desidera includere una proprietà dentro la mia funzione in questo modofreccia Funzioni e questo

var person = { 
    name: "jason", 

    shout:() => console.log("my name is ", this.name) 
} 

person.shout() // Should print out my name is jason 

Tuttavia, quando si esegue questa console codice registra solo my name is. Che cosa sto facendo di sbagliato?

+0

http://www.es6fiddle.net/ – jason328

risposta

19

Risposta breve: this punti alla vicina legato this - nel codice fornito this si trova nel campo di applicazione racchiude.

Più rispondere: funzioni freccia legano la loro this quando vengono createdo not have this, arguments or other special names bound at all - quando viene creato l'oggetto del nome this si trova nel perimetro che racchiude, non l'oggetto person. Si può vedere più chiaramente spostando la dichiarazione:

var person = { 
    name = "Jason" 
}; 
person.shout =() => console.log("Hi, my name is", this); 

E ancora più chiaro quando tradotto in una vaga approssimazione della sintassi freccia in ES5:

var person = { 
    name = "Jason" 
}; 
var shout = function() { 
    console.log("Hi, my name is", this.name); 
}.bind(this); 
person.shout = shout; 

In entrambi i casi, this (per la funzione shout) punta allo stesso campo in cui è definito person, non al nuovo ambito a cui è assegnata la funzione quando viene aggiunto all'oggetto person.

È Non puoi funzioni freccia rendere il lavoro in quel modo, ma, come @kamituel sottolinea in his answer, si possibile sfruttare il metodo di modello di dichiarazione più breve in ES6 per ottenere simili risparmio di spazio:

var person = { 
    name: "Jason", 
    // ES6 "method" declaration - leave off the ":" and the "function" 
    shout() { 
    console.log("Hi, my name is", this.name); 
    } 
}; 
+0

Grazie. Capisco il problema ora! Le funzioni di freccia – jason328

+0

si chiamano espressioni lambda –

+1

il collegamento getify è morto, può essere visualizzato su https://web.archive.org/web/20160625172303/http://blog.getify.com/arrow-this/ – zowers

2

Qui il valore di questo all'interno della funzione è determinato da dove viene definita la funzione della freccia e non da dove viene utilizzata.

Così this fa riferimento a oggetto globale/finestra se non avvolto in altri namespace

14

concordate con @Sean Vieira - in questo caso this è legato all'oggetto globale (o, come sottolineato nel commento, più in generale, a un ambito che racchiude).

Se si desidera avere una sintassi più breve, esiste un'altra opzione: i valori letterali degli oggetti avanzati supportano la sintassi breve per le funzioni di proprietà. this sarà legato come ci si aspetta lì. Vedere shout3():

window.name = "global"; 

var person = { 
    name: "jason", 

    shout: function() { 
     console.log("my name is ", this.name); 
    }, 
    shout2:() => { 
     console.log("my name is ", this.name); 
    }, 
    // Shorter syntax 
    shout3() { 
     console.log("my name is ", this.name); 
    } 
}; 

person.shout(); // "jason" 
person.shout2(); // "global" 
person.shout3(); // "jason" 
+2

Suvviato, ma nota 'questo' non sarà necessariamente l'oggetto globale. – Oriol

+0

@Oriol true, annotato - ho assunto che questo è il codice di livello superiore. Grazie! – kamituel

+0

great (Y) @kamituel –

0

Il problema è che (MDN)

Un'espressione funzione freccia [...] si lega lessicalmente questo valore.

Le funzioni freccia acquisiscono questo valore del contesto che lo racchiude.

Pertanto, il valore di this in quella funzione sarà il valore di this in cui si crea l'oggetto letterale. Probabilmente, questo sarà window in modalità non rigida e undefined in modalità rigorosa.

Per risolvere il problema, è necessario utilizzare un normale funzione:

var person = { 
    name: "jason", 
    shout: function(){ console.log("my name is ", this.name) } 
} 
person.shout(); 
0

La risposta accettata è eccellente, conciso e chiaro, ma io elaborerà un po 'su quello che ha detto Sean Vieira:

Le funzioni freccia non hanno questo argomento o altri nomi speciali vincolati.

Poiché la funzione freccia non ha un "questo", utilizza "questo" del genitore. "questo" punta sempre al genitore, e il genitore dell'oggetto persona è Window (se sei in un browser).

per dimostrarlo eseguire questo nella console:

var person = { 
    name: "Jason", 
    anotherKey: this 
} 
console.log(person.anotherKey) 

si otterrà l'oggetto Finestra.

Trovo che questo sia un modo davvero utile per pensarci. Non è esattamente la storia completa, poiché ciò che è il "questo" di un oggetto letterale è un'altra discussione.

Problemi correlati