Il valore di questa parola chiave

La parola chiave this fa riferimento al valore dell'oggetto associato al funzione al momento della chiamata, vale a dire che il suo valore è diverso sul fatto che una funzione venga chiamata come metodo, come funzione autonoma o come costruttore.

Quando viene chiamata una funzione, crea un'istanza della parola chiave this dietro le scene come riferimento all'oggetto che contiene la funzione, assegnando alle proprietà e ai metodi definiti nel suo ambito. L'utilizzo di this è in qualche modo simile all'utilizzo di una variabile dichiarata con const. Come una costante, this non può essere rimosso e il suo valore non può essere riassegnato, ma i metodi e le proprietà dell'oggetto che la parola chiave this può essere modificato.

Associazione globale

Al di fuori di una funzione o del contesto di un oggetto, this si riferisce alla globalThis, che fa riferimento all'oggetto globale nella maggior parte degli ambienti JavaScript. Nel contesto di uno script eseguito su un browser web, l'oggetto globale è l'oggetto window:

this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}

In Node.js, globalThis è l'oggetto global:

$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}

Al di fuori della modalità con restrizioni, this si riferisce anche all'oggetto globale all'interno di un oggetto autonomo funzione, perché il Window principale è l'oggetto che effettivamente "possiede" queste funzioni.

function myFunction() {
    console.log( this );
}
myFunction();
> Window {...}

(function() {
    console.log( this );
}());
> Window {...}

Quando utilizzi la modalità con restrizioni, il valore di this è undefined all'interno di una versione autonoma :

(function() {
    "use strict";
    console.log( this );
}());
> undefined

Prima dell'introduzione della modalità con restrizioni, un valore null o undefined per this viene sostituito da un riferimento all'oggetto globale. A volte potresti vedere associazione globale denominata "associazione predefinita" a causa di questo comportamento precedente.

Associazione implicita

Quando una funzione viene chiamata come metodo di un oggetto, un'istanza di this all'interno questo metodo fa riferimento all'oggetto che lo contiene, concedendo l'accesso e le relative proprietà:

let myObject = {
    myValue: "This is my string.",
    myMethod() {
            console.log( this.myValue );
    }
};

myObject.myMethod();
> "This is my string."

Potrebbe sembrare che il valore di this dipenda da come una funzione e dalle sue che contengono gli oggetti. Il contesto per il valore di this è invece il contesto di esecuzione attuale. In questo caso, il contesto di esecuzione è che L'oggetto myObject sta chiamando il metodo myMethod, quindi myObject è il valore per this. Questo potrebbe sembrare un aspetto tecnico nel contesto della precedente esempi, ma per utilizzi più avanzati di this, è una distinzione essenziale per più file.

In generale, usa this in modi che non prevedono che il codice circostante abbia a una particolare struttura. L'eccezione a questa regola è ES5. Funzioni delle frecce.

this nelle funzioni freccia

Nelle funzioni a freccia, this si risolve in un'associazione in un ambiente che include errori sessuali. Ciò significa che this in una funzione a freccia si riferisce al valore di this nella relativa il contesto più vicino:

let myObject = {
    myMethod() { console.log( this ); },
    myArrowFunction: () => console.log( this ),
    myEnclosingMethod: function () {
        this.myArrowFunction = () => { console.log(this) };
    }
};

myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }

myObject.myArrowFunction();
> Window {...}

Nell'esempio precedente, myObject.myMethod() registra myObject come oggetto che "possiede" questo metodo, ma myObject.myArrowFunction() restituisce globalThis (o undefined), perché l'istanza di this all'interno della funzione freccia si riferisce invece all'ambito che include

Nell'esempio seguente, myEnclosingMethod crea una funzione a freccia nella che lo contiene quando viene eseguita. L'istanza di this all'interno La funzione freccia ora si riferisce al valore di this all'interno del relativo , ovvero il metodo che contiene la funzione freccia. Poiché il valore di this all'interno di myEnclosingMethod si riferisce a myObject, dopo definisci la funzione freccia, this all'interno della funzione freccia si riferisce anche a myObject:

let myObject = {
    myMethod() { console.log( this ); },
    myEnclosingMethod: function () {
        this.myArrowFunction = () => { console.log(this) };
    }
};

myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }

Associazione esplicita

L'associazione implicita gestisce la maggior parte dei casi d'uso per l'uso di this. Tuttavia, a volte potrebbe essere necessario il valore di this per rappresentare un'esecuzione specifica contesto, anziché quello ipotizzato. Un testo illustrativo, se un po' obsoleto, esempio funziona con this all'interno della funzione di callback di un setTimeout, poiché questo callback ha un contesto di esecuzione univoco:

var myObject = {
  myString: "This is my string.",
  myMethod() {
    console.log( this.myString );
  }
};
myObject.myMethod();
> "This is my string."

setTimeout( myObject.myMethod, 100 );
> undefined

Anche se da allora questa specifica carenza di setTimeout è stata colmata altre funzionalità, problemi simili di "perdita" this già affrontati creando un riferimento esplicito al valore di this nell'ambito del contesto previsto. A volte potresti vedere istanze dell'assegnazione di this a una variabile utilizzando identificatori come that, self o _this nella versione precedente codebase. Queste sono convenzioni comuni per gli identificatori per variabili contenenti un È stato superato il valore this.

Quando chiami una funzione utilizzando i metodi call(), bind() o apply(), this fa riferimento esplicitamente all'oggetto chiamato:

let myFunction = function() {
    console.log( this.myValue );
}

let myObject = {
   "myValue" : "This is my string."
 };

myFunction.call( myObject );
> "This is my string."
var myObject = {
  myString: "This is my string.",
  myMethod() {
    console.log( this.myString );
  }
};

setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."

L'associazione esplicita sostituisce il valore this fornito dall'associazione implicita.

let myObject = {
    "myValue" : "This string sits alongside myMethod.",
    myMethod() {
        console.log( this.myValue );
    }
};
let myOtherObject = {
    "myValue" : "This is a string in another object entirely.",
};

myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."

Se una funzione viene chiamata in un modo che imposterebbe il valore di this su undefined o null, questo valore è sostituito da globalThis al di fuori del limite massimo modalità:

let myFunction = function() {
    console.log( this );
}

myFunction.call( null );
> Window {...}

Analogamente, se una funzione viene chiamata in un modo che darebbe a this una funzione , questo valore viene sostituito con oggetto wrapper del valore primitivo fuori dalla modalità con restrizioni:

let myFunction = function() {
    console.log( this );
}

let myNumber = 10;

myFunction.call( myNumber );
> Number { 10 }

In modalità con restrizioni, un valore this passato non viene forzato in alcun modo a un oggetto, anche se si tratta di un valore primitivo, null o undefined:

"use strict";
let myFunction = function() {
    console.log( this );
}

let myNumber = 10;

myFunction.call( myNumber );
> 10

myFunction.call( null );
> null

new associazione

Quando una class viene utilizzata come costruttore utilizzando Parola chiave new, this si riferisce all'istanza appena creata:

class MyClass {
    myString;
    constructor() {
        this.myString = "My string.";
    }
    logThis() {
        console.log( this );
    }
}
const thisClass = new MyClass();

thisClass.logThis();
> Object { myString: "My string." }

Analogamente, il valore di this all'interno di una funzione costruttore chiamata utilizzando new si riferisce all'oggetto che viene creato:

function MyFunction() {
  this.myString = "My string.";
  this.logThis = function() {
    console.log( this );
  }
}
const myObject = new MyFunction();

myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }

Associazione gestore eventi

Nel contesto dei gestori di eventi, il valore di this fa riferimento all'oggetto che lo richiama. All'interno della funzione di callback di un gestore di eventi, significa this fa riferimento all'elemento associato al gestore:

let button = document.querySelector( "button" );

button.addEventListener( "click", function( event ) { console.log( this ); } );

Quando un utente interagisce con button nello snippet precedente, il risultato è l'oggetto elemento contenente lo stesso <button>:

> Button {}

Quando viene utilizzata una funzione freccia come callback di un listener di eventi, il valore di this viene nuovamente fornito dal contesto di esecuzione più vicino. In alto significa che this all'interno di una funzione di callback di gestore di eventi è globalThis (o undefined, in modalità con restrizioni):

let button = document.querySelector( "button" );

button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined

Come per qualsiasi altro oggetto, quando usi call(), bind() o apply() per fare riferimento alla funzione di callback di un listener di eventi, this fa riferimento esplicitamente all'oggetto:

let button = document.querySelector( "button" );
let myObject = {
    "myValue" : true
};
function handleClick() {
    console.log( this );
}

button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }

Verifica le tue conoscenze

Per uno script eseguito in un browser web, qual è l'oggetto globale a cui this fa riferimento quando utilizzato al di fuori di una funzione o contesto di un oggetto?

L'oggetto window
L'oggetto browser
L'oggetto undefined