Come funziona la parola chiave "this"?


Ho notato che non sembra esserci una chiara spiegazione di cosa sia la parola chiave this e di come sia correttamente (e in modo errato) utilizzata in JavaScript sul sito Stack Overflow.

Ho assistito a un comportamento molto strano con esso e non sono riuscito a capire perché si è verificato.

Come funziona this e quando dovrebbe essere usato?

Author: JJJ, 2010-06-27

20 answers

Consiglio di leggere L'articolo di Mike West Scope in JavaScript (specchio) prima. È un'introduzione eccellente e amichevole ai concetti di this e catene di ambito in JavaScript.

Una volta che inizi ad abituarti a this, le regole sono in realtà piuttosto semplici. Lo standard ECMAScript 5.1 definisce this:

§11.1.1 La parola chiave this

La parola chiave this valuta il valore del ThisBinding del contesto di esecuzione corrente

ThisBinding è qualcosa che l'interprete JavaScript mantiene mentre valuta il codice JavaScript, come un registro speciale della CPU che contiene un riferimento a un oggetto. L'interprete aggiorna il ThisBinding ogni volta che stabilisce un contesto di esecuzione in uno dei soli tre casi diversi:

1. Contesto di esecuzione globale iniziale

Questo è il caso del codice JavaScript che viene valutato al livello superiore, ad esempio quando direttamente all'interno di un <script>:

<script>
  alert("I'm evaluated in the initial global execution context!");

  setTimeout(function () {
      alert("I'm NOT evaluated in the initial global execution context.");
  }, 1);
</script>

Quando si valuta il codice nel contesto di esecuzione globale iniziale, ThisBinding è impostato sull'oggetto globale, window (§10.4.1.1).

Inserimento del codice eval

  • ...con una chiamata diretta a eval() ThisBinding rimane invariato; è lo stesso valore di ThisBinding del contesto di esecuzione chiamante(§10.4.2 (2)(a)).

  • ...se non tramite una chiamata diretta a eval()
    ThisBinding è impostato sul oggetto globale come se fosse in esecuzione nel contesto di esecuzione globale iniziale(§10.4.2 (1)).

§15.1.2.1.1 definisce cosa sia una chiamata diretta a eval(). Fondamentalmente, eval(...) è una chiamata diretta mentre qualcosa come (0, eval)(...) o var indirectEval = eval; indirectEval(...); è una chiamata indiretta a eval(). Vedila risposta di chuckj a (1, eval)('this') vs eval('this') in JavaScript? e ECMA-262-5 di Dmitry Soshnikov in dettaglio. Capitolo 2. Modalità rigorosa. per quando potresti utilizzare una chiamata indiretta eval().

Inserimento del codice funzione

Ciò si verifica quando si chiama una funzione. Se una funzione viene chiamata su un oggetto, ad esempio in obj.myMethod() o l'equivalente obj["myMethod"](), ThisBinding viene impostato sull'oggetto (obj nell'esempio; §13.2.1). Nella maggior parte degli altri casi, ThisBinding è impostato sull'oggetto globale(§10.4.3).

Il motivo per cui si scrive" nella maggior parte degli altri casi " è perché ci sono otto funzioni integrate ECMAScript 5 che consentono ThisBinding da specificare nella lista argomenti. Queste funzioni speciali prendono un cosiddetto thisArg che diventa ThisBinding quando si chiama la funzione (§10.4.3).

Queste speciali funzioni integrate sono:

  • Function.prototype.apply( thisArg, argArray )
  • Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Array.prototype.every( callbackfn [ , thisArg ] )
  • Array.prototype.some( callbackfn [ , thisArg ] )
  • Array.prototype.forEach( callbackfn [ , thisArg ] )
  • Array.prototype.map( callbackfn [ , thisArg ] )
  • Array.prototype.filter( callbackfn [ , thisArg ] )

Nel caso delle funzioni Function.prototype, vengono chiamate su una funzione oggetto, ma piuttosto che impostare ThisBinding all'oggetto funzione, ThisBinding è impostato su thisArg.

Nel caso delle funzioni Array.prototype, il dato callbackfn viene chiamato in un contesto di esecuzione in cui ThisBinding è impostato su thisArg se fornito; in caso contrario, all'oggetto globale.

Queste sono le regole per il semplice JavaScript. Quando si inizia a utilizzare le librerie JavaScript (ad esempio jQuery), è possibile che alcune funzioni di libreria manipolino il valore di this. Gli sviluppatori di quelli Le librerie JavaScript lo fanno perché tende a supportare i casi d'uso più comuni e gli utenti della libreria in genere trovano questo comportamento più conveniente. Quando si passano funzioni di callback che fanno riferimento a this alle funzioni di libreria, è necessario fare riferimento alla documentazione per qualsiasi garanzia su quale sia il valore di this quando viene chiamata la funzione.

Se ti stai chiedendo come una libreria JavaScript manipola il valore di this, la libreria utilizza semplicemente uno dei Funzioni JavaScript che accettano un thisArg. Anche tu puoi scrivere la tua funzione prendendo una funzione di callback e thisArg:

function doWork(callbackfn, thisArg) {
    //...
    if (callbackfn != null) callbackfn.call(thisArg);
}
C'è un caso speciale che non ho ancora menzionato. Quando si costruisce un nuovo oggetto tramite l'operatore new, l'interprete JavaScript crea un nuovo oggetto vuoto, imposta alcune proprietà interne e quindi chiama la funzione di costruzione sul nuovo oggetto. Pertanto, quando una funzione viene chiamata in un contesto del costruttore, il valore di this è il nuovo oggetto che interprete creato:
function MyType() {
    this.someData = "a string";
}

var instance = new MyType();
// Kind of like the following, but there are more steps involved:
// var instance = {};
// MyType.call(instance);

Solo per divertimento, prova la tua comprensione con alcuni esempi

Per rivelare le risposte, mouse sopra le caselle di colore giallo chiaro.

  1. Qual è il valore di this sulla riga contrassegnata? Perché?

    window - La riga contrassegnata viene valutata nel contesto di esecuzione globale iniziale.

    if (true) {
        // What is `this` here?
    }
    
  2. Qual è il valore di this sulla riga contrassegnata quando viene eseguito obj.staticFunction()? Perché?

    obj - Quando si chiama una funzione su un oggetto, Questobinding è impostato sull'oggetto.

    var obj = {
        someData: "a string"
    };
    
    function myFun() {
        return this // What is `this` here?
    }
    
    obj.staticFunction = myFun;
    
    console.log("this is window:", obj.staticFunction() == window);
    console.log("this is obj:", obj.staticFunction() == obj);
      
  3. Qual è il valore di this sulla riga contrassegnata? Perché?

    window

    In questo esempio, l'interprete JavaScript inserisce il codice funzione, ma perché myFun/obj.myMethod non viene chiamato su un oggetto, ThisBinding è impostato su window.

    Questo è diverso da Python, in cui l'accesso a un metodo (obj.myMethod) crea un oggetto metodo associato .

    var obj = {
        myMethod: function () {
            return this; // What is `this` here?
        }
    };
    var myFun = obj.myMethod;
    console.log("this is window:", myFun() == window);
    console.log("this is obj:", myFun() == obj);
      
  4. Qual è il valore di this sulla riga contrassegnata? Perché?

    window

    Questo è stato complicato. Quando si valuta il codice eval, this è obj. Tuttavia, nel codice eval, myFun non viene chiamato su un oggetto, quindi ThisBinding è impostato su window per la chiamata.

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        myMethod: function () {
            eval("myFun()");
        }
    };
    
  5. Qual è il valore di this sulla riga contrassegnata? Perché?

    obj

    La riga myFun.call(obj); richiama la funzione speciale incorporata Function.prototype.call(), che accetta thisArg come primo argomento.

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        someData: "a string"
    };
    console.log("this is window:", myFun.call(obj) == window);
    console.log("this is obj:", myFun.call(obj) == obj);
      
 1176
Author: Daniel Trebbien, 2018-05-27 03:41:28

La parola chiave this si comporta in modo diverso in JavaScript rispetto ad altre lingue. Nei linguaggi orientati agli oggetti, la parola chiave this si riferisce all'istanza corrente della classe. In JavaScript il valore di {[12] } è determinato principalmente dal contesto di invocazione della funzione (context.function()) e dove si chiama.

1. Se utilizzato in un contesto globale

Quando si utilizza this nel contesto globale, è associato all'oggetto globale (window in browser)

document.write(this);  //[object Window]

Quando si utilizza this all'interno di una funzione definita nel contesto globale, this è ancora associato all'oggetto globale poiché la funzione è in realtà un metodo di contesto globale.

function f1()
{
   return this;
}
document.write(f1());  //[object Window]

Sopra f1 è fatto un metodo di oggetto globale. Quindi possiamo anche chiamarlo su window oggetto come segue:

function f()
{
    return this;
}

document.write(window.f()); //[object Window]

2. Quando viene utilizzato all'interno del metodo dell'oggetto

Quando si utilizza la parola chiave this all'interno di un metodo object, this è associato a" oggetto che racchiude.

var obj = {
    name: "obj",
    f: function () {
        return this + ":" + this.name;
    }
};
document.write(obj.f());  //[object Object]:obj

Sopra ho messo la parola immediata tra virgolette. È per fare il punto che se annidi l'oggetto all'interno di un altro oggetto, allora this è associato al genitore immediato.

var obj = {
    name: "obj1",
    nestedobj: {
        name:"nestedobj",
        f: function () {
            return this + ":" + this.name;
        }
    }            
}

document.write(obj.nestedobj.f()); //[object Object]:nestedobj

Anche se si aggiunge esplicitamente la funzione all'oggetto come metodo, segue comunque le regole precedenti, ovvero this punta ancora all'oggetto genitore immediato.

var obj1 = {
    name: "obj1",
}

function returnName() {
    return this + ":" + this.name;
}

obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1

3. Quando si invoca la funzione senza contesto

Quando si utilizza this all'interno funzione invocata senza alcun contesto (cioè non su alcun oggetto), è associata all'oggetto globale (window nel browser) (anche se la funzione è definita all'interno dell'oggetto) .

var context = "global";

var obj = {  
    context: "object",
    method: function () {                  
        function f() {
            var context = "function";
            return this + ":" +this.context; 
        };
        return f(); //invoked without context
    }
};

document.write(obj.method()); //[object Window]:global 

Provare tutto con le funzioni

Possiamo provare anche i punti sopra con le funzioni. Tuttavia ci sono alcune differenze.

  • Sopra abbiamo aggiunto membri agli oggetti usando la notazione letterale dell'oggetto. Possiamo aggiungere membri alle funzioni usando this. specificare loro.
  • La notazione letterale dell'oggetto crea un'istanza di oggetto che possiamo usare immediatamente. Con la funzione potremmo aver bisogno di creare prima la sua istanza usando l'operatore new.
  • Anche in un approccio letterale dell'oggetto, possiamo aggiungere esplicitamente membri all'oggetto già definito usando l'operatore dot. Questo viene aggiunto solo all'istanza specifica. Tuttavia ho aggiunto la variabile al prototipo della funzione in modo che si rifletta in tutte le istanze della funzione.

Di seguito Ho provato tutte le cose che abbiamo fatto con Object e this sopra, ma creando prima la funzione invece di scrivere direttamente un oggetto.

/********************************************************************* 
  1. When you add variable to the function using this keyword, it 
     gets added to the function prototype, thus allowing all function 
     instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
    this.name = "ObjDefinition";
    this.getName = function(){                
        return this+":"+this.name;
    }
}        

obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition   

/********************************************************************* 
   2. Members explicitly added to the function protorype also behave 
      as above: all function instances have their own copy of the 
      variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
    return "v"+this.version; //see how this.version refers to the
                             //version variable added through 
                             //prototype
}
document.write(obj1.getVersion() + "<br />"); //v1

/********************************************************************* 
   3. Illustrating that the function variables added by both above 
      ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
    this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1

obj2.incrementVersion();      //incrementing version in obj2
                              //does not affect obj1 version

document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1

/********************************************************************* 
   4. `this` keyword refers to the immediate parent object. If you 
       nest the object through function prototype, then `this` inside 
       object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj', 
                                    getName1 : function(){
                                        return this+":"+this.name;
                                    }                            
                                  };

document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj

/********************************************************************* 
   5. If the method is on an object's prototype chain, `this` refers 
      to the object the method was called on, as if the method was on 
      the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
                                    //as its prototype
obj3.a = 999;                       //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
                                    //calling obj3.fun() makes 
                                    //ProtoObj.fun() to access obj3.a as 
                                    //if fun() is defined on obj3

4. Quando viene utilizzato all'interno della funzione costruttore.

Quando la funzione viene utilizzata come costruttore (cioè quando viene chiamata con la parola chiave new), this all'interno del corpo della funzione punta al nuovo oggetto in costruzione.

var myname = "global context";
function SimpleFun()
{
    this.myname = "simple function";
}

var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
//   object being constructed thus adding any member
//   created inside SimipleFun() using this.membername to the
//   object being constructed
//2. And by default `new` makes function to return newly 
//   constructed object if no explicit return value is specified

document.write(obj1.myname); //simple function

5. Quando viene utilizzato all'interno della funzione definita sulla catena prototipo

Se il il metodo si trova sulla catena prototipo di un oggetto, this all'interno di tale metodo si riferisce all'oggetto su cui è stato chiamato il metodo, come se il metodo fosse definito sull'oggetto.

var ProtoObj = {
    fun: function () {
        return this.a;
    }
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun() 
//to be the method on its prototype chain

var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999

//Notice that fun() is defined on obj3's prototype but 
//`this.a` inside fun() retrieves obj3.a   

6. All'interno delle funzioni call(), apply() e bind ()

  • Tutti questi metodi sono definiti su Function.prototype.
  • Questi metodi consentono di scrivere una funzione una volta e invocarla in un contesto diverso. In altre parole, consentono di specificare il valore di this che verrà utilizzato mentre la funzione è in esecuzione. Prendono anche tutti i parametri da passare alla funzione originale quando viene invocato.
  • fun.apply(obj1 [, argsArray]) Imposta obj1 come valore di this all'interno di fun() e chiama fun() passando elementi di argsArray come argomenti.
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Imposta obj1 come valore di this all'interno di fun() e chiama fun() passando arg1, arg2, arg3, ... come argomenti.
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Restituisce il riferimento alla funzione fun con this all'interno di fun associato a obj1 e i parametri di fun associati ai parametri specificati arg1, arg2, arg3,....
  • Ormai la differenza tra apply, call e bind deve essere diventato evidente. apply consente di specificare gli argomenti per funzionare come oggetto simile a un array, ovvero un oggetto con una proprietà numerica length e le corrispondenti proprietà intere non negative. Considerando che call consente di specificare direttamente gli argomenti della funzione. Sia apply che call richiamano immediatamente la funzione nel contesto specificato e con gli argomenti specificati. D'altra parte, bind restituisce semplicemente la funzione associata al valore this specificato e agli argomenti. Possiamo catturare il riferimento a questa funzione restituita assegnandolo a una variabile e in seguito possiamo chiamarlo in qualsiasi momento.
function add(inc1, inc2)
{
    return this.a + inc1 + inc2;
}

var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
      //above add.call(o,5,6) sets `this` inside
      //add() to `o` and calls add() resulting:
      // this.a + inc1 + inc2 = 
      // `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
      // `o.a` i.e. 4 + 5 + 6 = 15

var g = add.bind(o, 5, 6);       //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />");    //15

var h = add.bind(o, 5);          //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
      // 4 + 5 + 6 = 15
document.write(h() + "<br />");  //NaN
      //no parameter is passed to h()
      //thus inc2 inside add() is `undefined`
      //4 + 5 + undefined = NaN</code>

7. this gestori di eventi interni

  • Quando si assegna la funzione direttamente ai gestori di eventi di un elemento, l'uso di this direttamente all'interno della funzione di gestione elemento corrispondente. Tale assegnazione diretta della funzione può essere eseguita utilizzando il metodo addeventListener o attraverso i tradizionali metodi di registrazione degli eventi come onclick.
  • Allo stesso modo, quando si utilizza this direttamente all'interno della proprietà event (come <button onclick="...this..." >) dell'elemento, si riferisce all'elemento.
  • Tuttavia l'uso di this indirettamente attraverso l'altra funzione chiamata all'interno della funzione di gestione degli eventi o della proprietà dell'evento si risolve nell'oggetto globale window.
  • Lo stesso sopra il comportamento si ottiene quando si collega la funzione al gestore eventi utilizzando il metodo del modello di registrazione eventi di Microsoft attachEvent. Invece di assegnare la funzione al gestore di eventi (e quindi rendere il metodo di funzione dell'elemento), chiama la funzione sull'evento (chiamandola effettivamente in un contesto globale).

Consiglio di provare meglio questo in JSFiddle .

<script> 
    function clickedMe() {
       alert(this + " : " + this.tagName + " : " + this.id);
    } 
    document.getElementById("button1").addEventListener("click", clickedMe, false);
    document.getElementById("button2").onclick = clickedMe;
    document.getElementById("button5").attachEvent('onclick', clickedMe);   
</script>

<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>

<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />

<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />

IE only: <button id="button5">click() "attached" using attachEvent() </button>
 127
Author: Mahesha999, 2015-05-07 13:42:03

Javascript this

Semplice funzione di invocazione

Considera la seguente funzione:

function foo() {
    console.log("bar");
    console.log(this);
}
foo(); // calling the function

Si noti che lo stiamo eseguendo nella modalità normale, cioè la modalità rigorosa non viene utilizzata.

Quando viene eseguito in un browser, il valore di this verrà registrato come window. Questo perché window è la variabile globale nell'ambito di un browser Web.

Se si esegue questo stesso pezzo di codice in un ambiente come node.js, this si riferirebbe al globale variabile nella tua app.

Ora se lo eseguiamo in modalità rigorosa aggiungendo l'istruzione "use strict"; all'inizio della dichiarazione della funzione, this non farà più riferimento alla variabile globale in nessuno dei due envirnoments. Questo è fatto per evitare confusioni nella modalità rigorosa. this sarebbe, in questo caso solo log undefined, perché è quello che è, non è definito.

Nei seguenti casi, vedremo come manipolare il valore di this.

Chiamata di una funzione su un oggetto

Ci sono diversi modi per farlo. Se hai chiamato metodi nativi in Javascript come forEach e slice, dovresti già sapere che la variabile this in quel caso si riferisce al Object su cui hai chiamato quella funzione (Nota che in javascript, quasi tutto è un Object, incluso Arrays e Function s). Prendi il seguente codice per esempio.

var myObj = {key: "Obj"};
myObj.logThis = function () {
    // I am a method
    console.log(this);
}
myObj.logThis(); // myObj is logged

Se un Object contiene una proprietà che contiene un Function, la proprietà viene chiamata metodo. Questo il metodo, quando viene chiamato, avrà sempre la variabile this impostata su Object a cui è associato. Questo è vero per entrambe le modalità rigorose e non rigorose.

Si noti che se un metodo viene memorizzato (o meglio copiato) in un'altra variabile, il riferimento a this non viene più conservato nella nuova variabile. Ad esempio:

// continuing with the previous code snippet

var myVar = myObj.thisMethod;
myVar();
// logs either of window/global/undefined based on mode of operation

Considerando uno scenario più comunemente pratico:

var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself

La parola chiave new

Considera una funzione di costruttore in Javascript:

function Person (name) {
    this.name = name;
    this.sayHello = function () {
        console.log ("Hello", this);
    }
}

var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`

Come funziona? Bene, vediamo cosa succede quando usiamo la parola chiave new.

  1. Chiamare la funzione con la parola chiave new inizializzerebbe immediatamente un Object di tipo Person.
  2. Il costruttore di questo Object ha il suo costruttore impostato su Person. Inoltre, si noti che typeof awal restituirebbe solo Object.
  3. A questo nuovo Object verrà assegnato il prototipo di Person.prototype. Ciò significa che qualsiasi metodo o proprietà nel Person prototype sarebbe disponibile per tutte le istanze di Person, incluso awal.
  4. La funzione Person stessa è ora invocata; this è un riferimento all'oggetto di nuova costruzione awal.

Abbastanza straighforward, eh?

Si noti che la specifica ufficiale ECMAScript no where afferma che tali tipi di funzioni sono funzioni constructor effettive. Sono solo funzioni normali e new può essere utilizzato su qualsiasi funzione. È solo che li usiamo come tali, e così chiamiamo solo loro come tali.

Chiamata di funzioni su funzioni: call e apply

Quindi sì, dal momento che functions sono anche Objects (e in effetti variabili di prima classe in Javascript), anche le funzioni hanno metodi che lo sono... bene, le funzioni stesse.

Tutte le funzioni ereditano dal globale Function, e due dei suoi molti metodi sono call e apply, ed entrambi possono essere utilizzati per manipolare il valore di this nella funzione su cui sono chiamati.

function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);

Questo è un tipico esempio di utilizzo di call. Fondamentalmente prende il primo parametro e imposta this nella funzione foo come riferimento a thisArg. Tutti gli altri parametri passati a call vengono passati alla funzione foo come argomenti.
Quindi il codice sopra registrerà {myObj: "is cool"}, [1, 2, 3] nella console. Bel modo per cambiare il valore di this in qualsiasi funzione.

apply è quasi uguale a call accetta che ci vogliono solo due parametri: thisArg e un array che contiene gli argomenti da passare alla funzione. Quindi la precedente chiamata call può essere tradotta in apply in questo modo:

foo.apply(thisArg, [1,2,3])

Si noti che call e apply possono sovrascrivere il valore di this impostato con l'invocazione del metodo dot di cui abbiamo discusso nel secondo punto. Abbastanza semplice:)

Presentazione.... bind!

bind è un fratello di call e apply. È anche un metodo ereditato da tutte le funzioni dal costruttore Function globale in Javascript. La differenza tra bind e call/apply sono entrambi call e apply invocheranno effettivamente la funzione. bind, d'altra parte, restituisce una nuova funzione con thisArg e arguments preimpostati. Facciamo un esempio per capire meglio questo:

function foo (a, b) {
    console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */

bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`

Vedi la differenza tra i tre? È sottile, ma sono usati in modo diverso. Come call e apply, bind supererà anche il valore di this impostato dall'invocazione del metodo dot.

Si noti inoltre che nessuna di queste tre funzioni modifica la funzione originale. call e apply restituiranno il valore da funzioni appena costruite mentre bind restituirà la funzione appena costruita stessa, pronta per essere chiamata.

Roba extra, copia questo

A volte, non ti piace il fatto che this cambia con scope, ambito appositamente nidificato. Dai un'occhiata al seguente esempio.

var myObj = {
    hello: function () {
        return "world"
        },
    myMethod: function () {
        // copy this, variable names are case-sensitive
        var that = this;
        // callbacks ftw \o/
        foo.bar("args", function () {
            // I want to call `hello` here
            this.hello(); // error
            // but `this` references to `foo` damn!
            // oh wait we have a backup \o/
            that.hello(); // "world"
        });
    }
  };

Nel codice precedente, vediamo che il valore di this è cambiato con l'ambito nidificato, ma volevamo il valore di this dall'originale ambito. Quindi abbiamo 'copiato' this in that e usato la copia invece di this. Intelligente, eh?

Indice:

  1. Cosa si tiene in this per impostazione predefinita?
  2. Cosa succede se chiamiamo la funzione come metodo con notazione Object-dot?
  3. Cosa succede se usiamo la parola chiave new?
  4. Come manipoliamo this con call e apply?
  5. Utilizzando bind.
  6. Copia this per risolvere i problemi annidati.
 49
Author: Awal Garg, 2014-10-27 09:40:54

"questo" riguarda l'ambito. Ogni funzione ha il proprio ambito, e poiché tutto in JS è un oggetto, anche una funzione può memorizzare alcuni valori in se stessa usando "questo". OOP 101 insegna che "questo" è applicabile solo alle istanze di un oggetto. Pertanto, ogni volta che viene eseguita una funzione, una nuova "istanza" di quella funzione ha un nuovo significato di "questo".

La maggior parte delle persone si confonde quando tenta di usare "questo" all'interno di funzioni di chiusura anonime come:

(function(value) {
    this.value = value;
    $('.some-elements').each(function(elt){
        elt.innerHTML = this.value;        // uh oh!! possibly undefined
    });
})(2);

Quindi qui, all'interno di each ()," this "non contiene il" valore " che ti aspetti (from

this.value = value;
sopra di esso). Quindi, per superare questo (nessun gioco di parole) problema, uno sviluppatore potrebbe:
(function(value) {
    var self = this;            // small change
    self.value = value;
    $('.some-elements').each(function(elt){
        elt.innerHTML = self.value;        // phew!! == 2 
    });
})(2);

Provalo; inizierai ad apprezzare questo modello di programmazione

 44
Author: arunjitsingh, 2014-10-29 05:00:41

this in Javascript si riferisce sempre al 'proprietario' della funzione che è in esecuzione.

Se non viene definito alcun proprietario esplicito, viene fatto riferimento al proprietario più in alto, l'oggetto window.

Quindi se l'ho fatto

function someKindOfFunction() {
   this.style = 'foo';
}

element.onclick = someKindOfFunction;

this farebbe riferimento all'oggetto element. Ma attenzione, molte persone commettono questo errore

<element onclick="someKindOfFunction()">

In quest'ultimo caso, si fa semplicemente riferimento alla funzione, non la si consegna all'elemento. Pertanto, this sarà fare riferimento all'oggetto finestra.

 14
Author: Seph, 2013-10-06 19:46:35

Poiché questo thread è aumentato, ho compilato alcuni punti per i lettori nuovi all'argomento this.

Come viene determinato il valore di this?

Usiamo questo simile al modo in cui usiamo i pronomi in lingue naturali come l'inglese: "John sta correndo veloce perché lui sta cercando di prendere il treno."Invece avremmo potuto scrivere "... John sta cercando di prendere il treno".

var person = {    
    firstName: "Penelope",
    lastName: "Barrymore",
    fullName: function () {

    // We use "this" just as in the sentence above:
       console.log(this.firstName + " " + this.lastName);

    // We could have also written:
       console.log(person.firstName + " " + person.lastName);
    }
}

this non viene assegnato un valore fino a quando un oggetto richiama la funzione in cui è definita. Nell'ambito globale, tutte le variabili e le funzioni globali sono definite sull'oggetto window. Pertanto, this in una funzione globale si riferisce (e ha il valore di) l'oggetto globale window.

Quando use strict, this nelle funzioni globali e anonime che non sono associate a nessun oggetto contiene un valore di undefined.

La parola chiave this è più fraintesa quando: 1) prendiamo in prestito un metodo che usa this, 2) noi assegna un metodo che utilizza this a una variabile, 3) una funzione che utilizza this viene passata come funzione di callback e 4) this viene utilizzata all'interno di una chiusura - una funzione interna. (2)

tavolo

Cosa riserva il futuro

Definito in ECMA Script 6, freccia-funzioni adottano il this associazione dal racchiudere (funzione o globale) ambito.

function foo() {
     // return an arrow function
     return (a) => {
     // `this` here is lexically inherited from `foo()`
     console.log(this.a);
  };
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };

var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!

Mentre le funzioni freccia forniscono un'alternativa all'utilizzo di bind(), è importante notare che essenzialmente stanno disabilitando il tradizionale meccanismo this a favore di un ambito lessicale più ampiamente compreso. (1)


Riferimenti:

  1. questo & Prototipi di oggetti , di Kyle Simpson. © 2014 Getify Soluzioni.
  2. javascriptissexy.com - http://goo.gl/pvl0GX
  3. Angus Croll - http://goo.gl/Z2RacU
 14
Author: carlodurso, 2014-10-30 03:58:06

Ogni funzione il contesto di esecuzione in javascript ha un ambito contesto questo parametro impostato da:

  1. Come viene chiamata la funzione (incluso come metodo oggetto, uso di call e apply , uso di new )
  2. Uso di bind
  3. Lessicalmente per le funzioni freccia (adottano il questo del loro contesto di esecuzione esterno)

Qualunque sia il contesto dell'ambito, è a cui fa riferimento "questo".

Puoi cambiare impostare il valore di questo ambito di applicazione contesto utilizzando func.call, func.apply oppure func.bind.

Per impostazione predefinita, e ciò che confonde la maggior parte dei principianti, quando un listener callback viene chiamato dopo che un evento è stato generato su un elemento DOM, il contesto dell'ambito questo valore della funzione è l'elemento DOM.

JQuery rende questo banale da cambiare con jQuery.proxy.

 11
Author: blockhead, 2017-04-26 03:54:14

Qui è una buona fonte di this in JavaScript.

Ecco il riassunto:

  • Globale questo

    In un browser, nell'ambito globale, this è l'oggetto window

    <script type="text/javascript">
      console.log(this === window); // true
      var foo = "bar";
      console.log(this.foo); // "bar"
      console.log(window.foo); // "bar"
    

    In node usando il repl, this è lo spazio dei nomi in alto. È possibile fare riferimento ad esso come global.

    >this
      { ArrayBuffer: [Function: ArrayBuffer],
        Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
        Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
        ...
    >global === this
     true
    

    In node esecuzione da uno script, this nell'ambito globale inizia come un oggetto vuoto. Non è lo stesso di global

    \\test.js
    console.log(this);  \\ {}
    console.log(this === global); \\ fasle
    
  • Funzione questo

Tranne nel caso di gestori di eventi DOM o quando viene fornito un thisArg (vedere più in basso), sia nel nodo che in un browser che utilizza this in una funzione che non viene chiamata con new fa riferimento all'ambito globale {

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();
    console.log(this.foo); //logs "foo"
</script>

Se si utilizza use strict;, nel qual caso this sarà undefined

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      "use strict";
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();  //Uncaught TypeError: Cannot set property 'foo' of undefined 
</script>

Se si chiama una funzione con new il {[15] } sarà un nuovo contesto, non farà riferimento al globale this.

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    new testThis();
    console.log(this.foo); //logs "bar"

    console.log(new testThis().foo); //logs "foo"
</script>
  • prototipo di questo

Le funzioni create diventano oggetti funzione. Ottengono automaticamente una speciale proprietà prototype, che è qualcosa a cui è possibile assegnare valori. Quando si crea un'istanza chiamando la funzione con new si ottiene l'accesso ai valori assegnati alla proprietà prototype. Si accede a tali valori utilizzando this.

function Thing() {
  console.log(this.foo);
}

Thing.prototype.foo = "bar";

var thing = new Thing(); //logs "bar"
console.log(thing.foo);  //logs "bar"

Di solito è un errore assegnare array o oggetti sul prototype. Se si desidera che le istanze abbiano ciascuna i propri array, crearle nella funzione, non nel prototipo.

function Thing() {
    this.things = [];
}

var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
  • oggetto questo

È possibile utilizzare this in qualsiasi funzione su un oggetto per fare riferimento ad altre proprietà su quell'oggetto. Questo non è lo stesso di un'istanza creata con new.

var obj = {
    foo: "bar",
    logFoo: function () {
        console.log(this.foo);
    }
};

obj.logFoo(); //logs "bar"
  • DOM evento questo

In un gestore di eventi DOM HTML, this è sempre un riferimento all'elemento DOM dell'evento allegato a

function Listener() {
    document.getElementById("foo").addEventListener("click",
       this.handleClick);
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs "<div id="foo"></div>"
}

var listener = new Listener();
document.getElementById("foo").click();

A meno che tu bind il contesto

function Listener() {
    document.getElementById("foo").addEventListener("click", 
        this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs Listener {handleClick: function}
}

var listener = new Listener();
document.getElementById("foo").click();
  • HTML questo

All'interno degli attributi HTML in cui è possibile inserire JavaScript, this è un riferimento all'elemento.

<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
  • valuta questo

È possibile utilizzare eval per accedere a this.

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    eval("console.log(this.foo)"); //logs "bar"
}

var thing = new Thing();
thing.logFoo();
  • con questo

È possibile utilizzare with per aggiungere this all'ambito corrente per leggere e scrivere valori su this senza fare esplicito riferimento a this.

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    with (this) {
        console.log(foo);
        foo = "foo";
    }
}

var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
  • jQuery questo

Il jQuery in molti punti avrà this fare riferimento a un elemento DOM.

<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
    this.click();
});
</script>
 9
Author: zangw, 2016-03-25 14:23:39

Daniel, bella spiegazione! Un paio di parole su questo e un buon elenco di this puntatore al contesto di esecuzione in caso di gestori di eventi.

In due parole, this in JavaScript punta l'oggetto da cui (o dal cui contesto di esecuzione) è stata eseguita la funzione corrente ed è sempre di sola lettura, non è possibile impostarlo comunque (un tale tentativo finirà con il messaggio 'Invalid left-hand side in assignment'.

Per i gestori di eventi: gestori di eventi in linea, ad esempio <element onclick="foo">, sovrascrivi qualsiasi altro gestore collegato prima e prima, quindi fai attenzione ed è meglio rimanere fuori dalla delega di eventi in linea. E grazie a Zara Alaverdyan che mi ha ispirato a questa lista di esempi attraverso un dibattito dissenziente:)

  • el.onclick = foo; // in the foo - obj
  • el.onclick = function () {this.style.color = '#fff';} // obj
  • el.onclick = function() {doSomething();} // In the doSomething - Window
  • el.addEventListener('click',foo,false) // in the foo - obj
  • el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
  • <button onclick="this.style.color = '#fff';"> // obj
  • <button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">
 8
Author: Arman McHitarian, 2013-04-23 12:57:30

C'è molta confusione su come "questa"parola chiave viene interpretata in JavaScript. Speriamo che questo articolo getterà tutti quelli a riposare una volta per tutte. E molto di più. Si prega di leggere attentamente l'intero articolo. Sappiate che questo articolo è lungo.

Indipendentemente dal contesto in cui viene utilizzato, "questo" fa sempre riferimento a"oggetto corrente" in Javascript. Tuttavia, ciò che il "oggetto corrente" è diverso in base a contesto . Il contesto può essere esattamente 1 dei 6 seguenti:

  1. Globale (cioè al di fuori di tutte le funzioni)
  2. All'interno della chiamata diretta "Funzione non vincolata" (cioè una funzione che non è stata vincolata chiamando functionName.bind)
  3. All'interno della chiamata indiretta "Funzione non legata" attraverso functionName.chiama e functionName.applica
  4. All'interno della chiamata "Bound Function" (cioè una funzione che è stata legata chiamando functionName.bind)
  5. Mentre la creazione di oggetti attraverso"nuovo"
  6. Gestore eventi DOM interno

Quanto segue descrive ciascuno di questi contesti uno per uno:

  1. Contesto globale (cioè al di fuori di tutte le funzioni):

    Esterno tutte le funzioni (cioè in contesto globale) il "corrente object " (e quindi il valore di "this" ) è sempre il oggetto"finestra" per i browser.

  2. All'interno della chiamata diretta "Funzione non legata" :

    All'interno di una chiamata diretta "Funzione non vincolata", l'oggetto che invocata la chiamata di funzione diventa l ' "oggetto corrente" (e quindi il valore di "questo"). Se una funzione viene chiamata senza una corrente esplicita oggetto, l'oggetto corrente è l'oggetto "finestra" (per la modalità non rigorosa) o non definito (Per la modalità rigorosa) . Qualsiasi funzione (o variabile) definita in Contesto globale diventa automaticamente una proprietà dell'oggetto"window".Per esempio Supponiamo che la funzione sia definita nel contesto globale come

    function UserDefinedFunction(){
        alert(this)
        }
    

    Diventa la proprietà dell'oggetto window, come se avessi definito come

    window.UserDefinedFunction=function(){
      alert(this)
    }  
    

    In "Modalità non rigorosa", chiamando / invocando questa funzione direttamente attraverso "UserDefinedFunction()"{[11] } chiamerà/invocherà automaticamente esso come " finestra.UserDefinedFunction ()" fare "finestra" come il "oggetto corrente" (e quindi il valore di "questo") all'interno di "UserDefinedFunction" .Richiamando questa funzione in "Modalità non rigorosa" si ottiene quanto segue

    UserDefinedFunction() // displays [object Window]  as it automatically gets invoked as window.UserDefinedFunction()
    

    In "Modalità rigorosa", chiamando/invocando la funzione direttamente attraverso "UserDefinedFunction ()" sarà "NON" chiama/invoca automaticamente come "finestra.UserDefinedFunction () " .Da qui la " corrente oggetto " (e il valore di "questo") all'interno "UserDefinedFunction"deve essere non definito . Richiamando questa funzione in "Modalità rigorosa" si ottiene quanto segue

    UserDefinedFunction() // displays undefined
    

    Tuttavia, richiamandolo esplicitamente usando l'oggetto window si ottiene quanto segue

    window.UserDefinedFunction() // "always displays [object Window]   irrespective of mode."
    

    Vediamo un altro esempio. Si prega di guardare quanto segue codice

     function UserDefinedFunction()
        {
            alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
        }
    
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
          }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    o1.f() // Shall display 1,2,undefined,undefined
    o2.f() // Shall display undefined,undefined,3,4
    

    Nell'esempio sopra vediamo che quando "UserDefinedFunction" era richiamato tramite o1, "questo" prende il valore di o1 e il viene visualizzato il valore delle sue proprietà "a" e "b". Valore di "c" e "d" sono stati mostrati come non definito come o1 fa non definire queste proprietà

    Allo stesso modo quando "UserDefinedFunction" è stato invocato attraverso o2 , "questo" prende il valore di o2 e il valore delle sue proprietà "c" e "d" viene visualizzato.Il valore di "a" e "b"è stato mostrato come non definitocome o2 non definisce queste proprietà.

  3. All'interno della chiamata indiretta "Funzione non legata" attraverso functionName.chiama e functionName.applica:

    Quando un "Non legato La funzione " viene chiamata attraverso functionName.chiama oppure functionName.applica, il "oggetto corrente" (e quindi il valore di "questo") è impostato sul valore di "questo"parametro (primo parametro) passato a chiama/applica . Il seguente codice dimostra lo stesso.

    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
           }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
    UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
    
    UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
    UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
    
    o1.f.call(o2) // Shall display undefined,undefined,3,4
    o1.f.apply(o2) // Shall display undefined,undefined,3,4
    
    o2.f.call(o1) // Shall display 1,2,undefined,undefined
    o2.f.apply(o1) // Shall display 1,2,undefined,undefined
    

    Il codice sopra mostra chiaramente che il valore" this "per qualsiasi" NON La funzione Bound " può essere modificata tramite call/apply . Inoltre, se il "questo" parametro non è passato esplicitamente a call / apply, "l'oggetto corrente" (e quindi il valore di "this") è impostato su "window" in modalità Non strict e "undefined" in modalità strict.

  4. All'interno della chiamata" Bound Function " (cioè una funzione che è stata vincolata chiamando functionName.bind):

    Una funzione associata è una funzione il cui "questo" valore è stato fisso. Il seguente codice ha dimostrato come "questo" funziona nel caso in cui della funzione legata

    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
              a:1,
              b:2,
              f:UserDefinedFunction,
              bf:null
           }
    var o2={
               c:3,
               d:4,
               f:UserDefinedFunction,
               bf:null
            }
    
    var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
    bound1() // Shall display 1,2,undefined,undefined
    
    var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
    bound2() // Shall display undefined,undefined,3,4
    
    var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
    bound3() // Shall display undefined,undefined,3,4
    
    var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
    bound4() // Shall display 1,2,undefined,undefined
    
    o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
    o1.bf() // Shall display undefined,undefined,3,4
    
    o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
    o2.bf() // Shall display 1,2,undefined,undefined
    
    bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    
    bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
    
    o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
    

    Come indicato nel codice sopra, " questo "valore per qualsiasi" Funzione associata" NON può essere modificato tramite call / apply. Inoltre, se il "questo" il parametro non è passato esplicitamente al bind, "oggetto corrente" (e quindi il valore di "this" ) è impostato su "window" in Non modalità rigorosa e "non definito" in modalità rigorosa. Un'altra cosa. Associazione di un la funzione già associata non modifica il valore di "this". Rimane impostato come valore impostato dalla prima funzione bind.

  5. Mentre la creazione di oggetti attraverso "nuovo":

    All'interno di una funzione di costruzione, il "oggetto corrente" (e quindi il valore di "this" ) fa riferimento all'oggetto attualmente in fase di creazione attraverso "nuovo" indipendentemente dallo stato di bind della funzione. Tuttavia se il costruttore è una funzione associata sarà chiamato con set predefinito di argomenti come impostato per la funzione associata.

  6. Gestore eventi DOM interno:

    Si prega di guardare il seguente frammento HTML

    <button onclick='this.style.color=white'>Hello World</button>
    <div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>
    

    Il "this" negli esempi precedenti si riferiscono all'elemento "button" e al elemento" div " rispettivamente.

    Nel primo esempio, il colore del carattere del pulsante deve essere impostato su bianco quando si fa clic.

    Nel secondo esempio quando il "div" elemento viene cliccato deve chiama la funzione OnDivClick con il suo secondo parametro riferimento all'elemento div cliccato. Tuttavia il valore di "questo" all'interno di OnDivClick NON DEVE fare riferimento al div cliccato elemento. Deve essere impostato come "oggetto finestra" o "undefined"nelle modalità Non strict e Strict rispettivamente (se OnDivClick è una funzione non associata ) o impostata su una funzione predefinita Legato valore (se OnDivClick è una funzione legata)

Quanto segue riassume l'intero articolo

  1. Nel contesto globale "questo" si riferisce sempre all'oggetto "finestra"

  2. Ogni volta che una funzione viene richiamata, viene richiamata nel contesto di un oggetto ("oggetto corrente"). Se l'oggetto corrente non è esplicitamente fornito, l'oggetto corrente è la finestra " oggetto" in NON Rigoroso Modalità e "non definito" in modalità Rigorosa per impostazione predefinita.

  3. Il valore di "this" all'interno di una funzione Non Legata è il riferimento all'oggetto nel contesto del quale viene invocata la funzione ( "current object")

  4. Il valore di "this" all'interno di una funzione non Vincolata può essere sovrascritto da chiama e applica i metodi della funzione.

  5. Il valore di "this" è fisso per una funzione associata e non può essere sovrascritto da chiama e applica i metodi della funzione.

  6. La funzione Binding e già associata non modifica il valore di "this". Rimane impostato come valore impostato dalla prima funzione bind.

  7. Il valore di "this" all'interno di un costruttore è l'oggetto che viene creato e inizializzato

  8. Il valore di "this" all'interno di un DOM in linea gestore eventi è riferimento all'elemento per il quale viene fornito il gestore eventi.

 8
Author: Arup Hore, 2017-03-03 07:34:25

Probabilmente l'articolo più dettagliato e completo su this è il seguente:

Spiegazione delicata della parola chiave 'this' in JavaScript

L'idea alla base di this è capire che i tipi di invocazione della funzione hanno l'importanza significativa nell'impostazione del valore this.


Quando si hanno problemi di identificazione this, non chiedere a:

Dov'è this tratto da?

Ma fare chiedere te stesso:

Come viene invocata la funzione ?

Per una funzione freccia (caso speciale di trasparenza del contesto) chiediti:

Quale valore ha thisdove la funzione freccia è definita?

Questa mentalità è corretta quando si tratta di this e ti salverà dal mal di testa.

 8
Author: Dmitri Pavlutin, 2018-08-22 06:19:50

Questa è la migliore spiegazione che ho visto. Capire JavaScript questo con chiarezza

Il questo riferimento si riferisce SEMPRE a (e contiene il valore di) un oggetto-un oggetto singolare - e di solito è usato all'interno di una funzione o un metodo, sebbene possa essere utilizzato al di fuori di una funzione nel globale ambito. Nota che quando usiamo la modalità rigorosa, questo contiene il valore di non definito nelle funzioni globali e nelle funzioni anonime che non lo sono legato a qualsiasi oggetto.

Ci sono quattro condizioni in cui questo può essere fonte di confusione:

  1. Quando passiamo un metodo (che usa questo) come parametro da utilizzare come funzione di callback.
  2. Un'altra istanza in cui questo viene frainteso è quando usiamo un metodo interno (una chiusura). È importante notare che le chiusure non possono accedere alla variabile this della funzione esterna utilizzando la parola chiave this perché la variabile this è accessibile solo dalla funzione stesso, non da funzioni interiori.
  3. Utilizzando questo quando un metodo viene assegnato a una variabile. Il questo valore è associato a un altro oggetto, se assegniamo un metodo che lo utilizza a una variabile
  4. Utilizzo di questo quando si utilizzano i metodi bind, apply e call.

Fornisce esempi di codice, le spiegazioni e le correzioni del codice che ho pensato fossero molto utili.

 6
Author: James Drinkard, 2016-07-12 19:03:54

È difficile ottenere una buona comprensione di JS, o scrivere più di qualsiasi cosa banale in esso, se non lo capisci a fondo. Non puoi semplicemente permetterti di fare un tuffo veloce :) Penso che il modo migliore per iniziare con JS sia guardare prima queste lezioni video di Douglas Crockford - http://yuiblog.com/crockford / , che copre questo e quello, e tutto il resto su JS.

 5
Author: tathagata, 2010-06-28 09:25:05

In termini pseudoclassici, il modo in cui molte lezioni insegnano la parola chiave 'this' è come un oggetto istanziato da un costruttore di classi o oggetti. Ogni volta che un nuovo oggetto viene costruito da una classe, immagina che sotto il cofano venga creata e restituita un'istanza locale di un oggetto 'this'. Ricordo che insegnava così:

function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}

var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;
 5
Author: mrmaclean89, 2017-09-16 22:11:43

this è uno dei concetti fraintesi in JavaScript perché si comporta in modo leggermente diverso da luogo a luogo. Semplicemente, this si riferisce al "proprietario" della funzione che stiamo attualmente eseguendo.

this aiuta a ottenere l'oggetto corrente (ovvero il contesto di esecuzione) con cui lavoriamo. Se capisci in quale oggetto viene eseguita la funzione corrente, puoi capire facilmente quale corrente this è

var val = "window.val"

var obj = {
    val: "obj.val",
    innerMethod: function () {
        var val = "obj.val.inner",
            func = function () {
                var self = this;
                return self.val;
            };

        return func;
    },
    outerMethod: function(){
        return this.val;
    }
};

//This actually gets executed inside window object 
console.log(obj.innerMethod()()); //returns window.val

//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val

console.log(obj.outerMethod()); //returns obj.val

Sopra creiamo 3 variabili con lo stesso nome "val". Uno nel contesto globale, uno all'interno di obj e l'altro all'interno del metodo interno di obj. JavaScript risolve gli identificatori all'interno di un particolare contesto risalendo la catena dell'ambito da local go global.


Pochi luoghi in cui this possono essere differenziati

Chiamare un metodo di un oggetto

var status = 1;
var helper = {
    status : 2,
    getStatus: function () {
        return this.status;
    }
};

var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2

var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1

Quando viene eseguita la line1, JavaScript stabilisce un contesto di esecuzione (EC) per la chiamata di funzione, impostando {[5] } sull'oggetto a cui fa riferimento qualunque sia venuto prima dell'ultimo".". quindi nell'ultima riga puoi capire che a() è stato eseguito nel contesto globale che è window.

Con Costruttore

this può essere usato per fare riferimento all'oggetto che si sta creando

function Person(name){
    this.personName = name;
    this.sayHello = function(){
        return "Hello " + this.personName;
    }
}

var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott

var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined

Quando viene eseguito un nuovo Person(), viene creato un oggetto completamente nuovo. Person viene chiamato e il suo this è impostato per fare riferimento a quel nuovo oggetto.

Chiamata di funzione

function testFunc() {
    this.name = "Name";
    this.myCustomAttribute = "Custom Attribute";
    return this;
}

var whatIsThis = testFunc();
console.log(whatIsThis); //window

var whatIsThis2 = new testFunc();
console.log(whatIsThis2);  //testFunc() / object

console.log(window.myCustomAttribute); //Custom Attribute 

Se ci manca new parola chiave, whatIsThis si riferisce al più globale contesto che può trovare(window)

Con gestori di eventi

Se il gestore eventi è in linea, this fa riferimento all'oggetto globale

<script type="application/javascript">
    function click_handler() {
        alert(this); // alerts the window object
    }
</script>

<button id='thebutton' onclick='click_handler()'>Click me!</button>

Quando si aggiunge il gestore di eventi tramite JavaScript, this si riferisce all'elemento DOM che ha generato l'evento.


 4
Author: Nipuna, 2017-05-23 12:02:59

Il valore di "this" dipende dal "contesto" in cui viene eseguita la funzione. Il contesto può essere qualsiasi oggetto o l'oggetto globale, cioè la finestra.

Quindi la semantica di "questo" è diversa dalle lingue tradizionali OOP. E causa problemi: 1. quando una funzione viene passata a un'altra variabile (molto probabilmente, una callback); e 2. quando una chiusura viene invocata da un metodo membro di una classe.

In entrambi i casi, questo è impostato su finestra.

 4
Author: Trombe, 2017-08-07 07:54:30

Whould questo aiuto? (La maggior parte della confusione di "questo" in javascript deriva dal fatto che generalmente non è collegato al tuo oggetto, ma all'ambito di esecuzione corrente might potrebbe non essere esattamente come funziona ma mi sembra sempre così see vedi l'articolo per una spiegazione completa)

 2
Author: Simon Groenewolt, 2010-06-27 13:15:45

Un po ' di informazioni su questa parola chiave

Registriamo la parola chiave this nella console nell'ambito globale senza più codice ma

console.log(this)

In Client / Browser this parola chiave è un oggetto globale che è window

console.log(this === window) // true

E

In Runtime server/Nodo/Javascript this parola chiave è anche un oggetto globale che è module.exports

console.log(this === module.exports) // true
console.log(this === exports) // true

Tenete a mente exports è solo un riferimento a module.exports

 2
Author: unclexo, 2018-07-25 07:04:35

Questo uso per l'Ambito proprio come questo

  <script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{
var txt='';
txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
 txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>

Il valore di txt1 e txt è lo stesso nell'esempio precedente $(questo)=#('#tbleName tbody tr') è lo stesso

 1
Author: PRADEEP SINGH Chundawat, 2016-04-06 07:15:05

Riepilogothis Javascript:

  • Il valore di thisè determinato da come la funzione viene invocata non, dove è stata creata!
  • Di solito il valore di this è determinato dall'Oggetto che rimane del punto. (window nello spazio globale)
  • Negli ascoltatori di eventi il valore di this si riferisce all'elemento DOM su cui è stato chiamato l'evento.
  • Quando in funzione viene chiamata con la parola chiave new il valore di this si riferisce alla nuova creazione oggetto
  • È possibile manipolare il valore di this con le funzioni: call, apply, bind

Esempio:

let object = {
  prop1: function () {console.log(this);}
}

object.prop1();   // object is left of the dot, thus this is object

const myFunction = object.prop1 // We store the function in the variable myFunction

myFunction(); // Here we are in the global space
              // myFunction is a property on the global object
              // Therefore it logs the window object
              
             

Listener di eventi di esempio:

document.querySelector('.foo').addEventListener('click', function () {
  console.log(this);   // This refers to the DOM element the eventListener was invoked from
})


document.querySelector('.foo').addEventListener('click', () => {
  console.log(this);  // Tip, es6 arrow function don't have their own binding to the this v
})                    // Therefore this will log the global object
.foo:hover {
  color: red;
  cursor: pointer;
}
<div class="foo">click me</div>

Costruttore di esempio:

function Person (name) {
  this.name = name;
}

const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object

console.log(me.name); 
// Therefore, the name property was placed on the object created with new keyword.
 0
Author: Willem van der Veen, 2018-08-21 17:12:28