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
.
cattura semplicemente il valore di 'this' dall'ambito contenente, trattandolo come qualsiasi o c'è una variabile. – Barmar
E 'solo così non devi fare il kludge di 'var self = this;' e quindi usare' self' nella funzione. – Barmar
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. –