Comment fonctionne le mot-clé" this"?


J'ai remarqué qu'il ne semble pas y avoir d'explication claire de ce qu'est le mot-clé this et comment il est correctement (et incorrectement) utilisé en JavaScript sur le site Stack Overflow.

J'ai été témoin d'un comportement très étrange avec elle et j'ai échoué à comprendre pourquoi cela s'est produit.

Comment fonctionne this et quand devrait-il être utilisé?

Author: JJJ, 2010-06-27

20 answers

Je recommande de lireL'article de Mike West Scope en JavaScript (miroir ) d'abord. C'est une excellente introduction conviviale aux concepts de this et de chaînes de portée en JavaScript.

Une fois que vous commencez à vous habituer à this, les règles sont en fait assez simples. La norme ECMAScript 5.1 définit this:

§11.1.1 Le mot-clé this

Le mot-clé this est évalué à la valeur du ThisBinding du contexte d'exécution actuel

ThisBinding est quelque chose que l'interpréteur JavaScript maintient lorsqu'il évalue le code JavaScript, comme un registre CPU spécial qui contient une référence à un objet. L'interpréteur met à jour ThisBinding chaque fois qu'il établit un contexte d'exécution dans l'un des trois cas différents:

1. Contexte d'exécution globale initiale

C'est le cas pour le code JavaScript qui est évalué au niveau supérieur, par exemple lorsque directement à l'intérieur d'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>

Lors de l'évaluation du code dans le contexte d'exécution globale initiale, ThisBinding est défini sur l'objet global, window (§10.4.1.1).

Saisie du code eval

  • ...par un appel direct à eval() ThisBinding reste inchangé; c'est la même valeur que ThisBinding du contexte d'exécution appelant(§10.4.2 (2)(a)).

  • ...sinon par un appel direct à eval()
    ThisBinding est défini sur le objet global comme si s'exécutait dans le contexte d'exécution global initial (§10.4.2 (1)).

§15.1.2.1.1 définit ce qu'est un appel direct à eval() est. Fondamentalement, eval(...) est un appel direct alors que quelque chose comme (0, eval)(...) ou var indirectEval = eval; indirectEval(...); est un appel indirect à eval(). Voir chuckj la réponse de à (1, eval) ("il") vs eval ("il") en JavaScript? et ECMA-262-5 de Dmitry Soshnikov en détail. Chapitre 2. Le Mode Strict. pour quand vous pourriez utilisez un appel indirect eval().

Saisie du code de fonction

Cela se produit lors de l'appel d'une fonction. Si une fonction est appelée sur un objet, comme dans obj.myMethod(), ou l'équivalent de obj["myMethod"](), puis ThisBinding est définie à l'objet (obj dans l'exemple; §13.2.1). Dans la plupart des autres cas, ThisBinding est défini sur l'objet global (§10.4.3).

La raison d'écrire "dans la plupart des autres cas" est qu'il existe huit fonctions intégrées à ECMAScript 5 qui permettent ThisBinding à spécifier dans la liste des arguments. Ces fonctions spéciales prennent un soi-disant {[26] } qui devient le ThisBinding lors de l'appel de la fonction (§10.4.3).

Ces fonctions intégrées spéciales sont:

  • 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 ] )

Dans le cas des fonctions Function.prototype, elles sont appelées sur une fonction objet, mais plutôt que de définir ThisBinding sur l'objet fonction, ThisBinding est défini sur thisArg.

Dans le cas des fonctions Array.prototype, le callbackfn donné est appelé dans un contexte d'exécution où ThisBinding est défini sur thisArg si fourni; sinon, à l'objet global.

Ce sont les règles pour JavaScript simple. Lorsque vous commencez à utiliser des bibliothèques JavaScript (par exemple jQuery), vous pouvez constater que certaines fonctions de bibliothèque manipulent la valeur de this. Les développeurs de ces Les bibliothèques JavaScript le font car elles ont tendance à prendre en charge les cas d'utilisation les plus courants, et les utilisateurs de la bibliothèque trouvent généralement ce comportement plus pratique. Lorsque vous passez des fonctions de rappel référençant this aux fonctions de bibliothèque, vous devez vous référer à la documentation pour toute garantie sur la valeur de this lorsque la fonction est appelée.

Si vous vous demandez comment une bibliothèque JavaScript manipule la valeur de this, la bibliothèque utilise simplement l'un des éléments intégrés Fonctions JavaScript acceptant un thisArg. Vous aussi, vous pouvez écrire votre propre fonction en prenant une fonction de rappel et thisArg:

function doWork(callbackfn, thisArg) {
    //...
    if (callbackfn != null) callbackfn.call(thisArg);
}

Il y a un cas particulier que je n'ai pas encore mentionné. Lors de la construction d'un nouvel objet via l'opérateur new, l'interpréteur JavaScript crée un nouvel objet vide, définit certaines propriétés internes, puis appelle la fonction constructeur sur le nouvel objet. Ainsi, lorsqu'une fonction est appelée dans un contexte constructeur, la valeur de this est le nouvel objet que interprète créé:

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

Juste pour le plaisir, testez votre compréhension avec quelques exemples

Pour révéler les réponses, passez la souris sur les cases jaune clair.

  1. Quelle est la valeur de this à la ligne marquée? Pourquoi?

    window - La ligne marquée est évaluée dans le contexte d'exécution globale initiale.

    if (true) {
        // What is `this` here?
    }
    
  2. Quelle est la valeur de this à la ligne marquée lorsque obj.staticFunction() est exécuté? Pourquoi?

    obj - Lors de l'appel d'une fonction sur un objet, ThisBinding est définie à l'objet.

    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. Quelle est la valeur de this à la ligne marquée? Pourquoi?

    window

    Dans cet exemple, l'interpréteur JavaScript entre le code de fonction, mais parce que myFun/obj.myMethod n'est pas appelé sur un objet, ThisBinding est défini sur window.

    Ceci est différent de Python, dans lequel accéder à une méthode (obj.myMethod) crée un objet de méthode lié.

    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. Quelle est la valeur de this à la ligne marquée? Pourquoi?

    window

    Celui-ci était délicat. Lors de l'évaluation du code eval, this est obj. Cependant, dans le code eval, myFun n'est pas appelé sur un objet, donc ThisBinding est défini sur window pour l'appel.

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        myMethod: function () {
            eval("myFun()");
        }
    };
    
  5. Quelle est la valeur de this à la ligne marquée? Pourquoi?

    obj

    La ligne myFun.call(obj); appelle la fonction intégrée spéciale Function.prototype.call(), qui accepte thisArg comme premier argument.

    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

Le mot-clé this se comporte différemment en JavaScript par rapport à un autre langage. Dans les langages orientés objet, le mot-clé this fait référence à l'instance actuelle de la classe. En JavaScript la valeur de this est essentiellement déterminée par le contexte d'invocation de la fonction (context.function()) et où il est appelé.

1. Lorsqu'il est utilisé dans un contexte global

Lorsque vous utilisez this dans un contexte global, il est lié à l'objet global (window dans le navigateur)

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

Lorsque vous utilisez this dans une fonction définie dans le contexte global, this est toujours lié à l'objet global car la fonction est en fait une méthode de contexte global.

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

Ci-dessus f1 est fait une méthode d'objet global. Ainsi, nous pouvons aussi l'appeler sur window objet comme suit:

function f()
{
    return this;
}

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

2. Lorsqu'il est utilisé à l'intérieur de la méthode d'objet

Lorsque vous utilisez le mot-clé this dans une méthode object, this est lié au " immédiat" englobante de l'objet.

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

Ci-dessus, j'ai mis le mot immédiat entre guillemets. C'est pour faire le point que si vous imbriquez l'objet dans un autre objet, alors this est lié au parent immédiat.

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

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

Même si vous ajoutez une fonction explicitement à l'objet en tant que méthode, elle suit toujours les règles ci-dessus, c'est-à-dire que this pointe toujours vers l'objet parent immédiat.

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. Lors de l'appel d'une fonction sans contexte

Lorsque vous utilisez this à l'intérieur de fonction qui est invoquée sans aucun contexte (c'est-à-dire pas sur un objet), elle est liée à l'objet global (window dans le navigateur) (même si la fonction est définie à l'intérieur de l'objet) .

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 

Essayer tout cela avec des fonctions

Nous pouvons essayer les points ci-dessus avec des fonctions aussi. Toutefois, il existe quelques différences.

  • Ci-dessus, nous avons ajouté des membres aux objets en utilisant la notation littérale de l'objet. Nous pouvons ajouter des membres aux fonctions en utilisant this. spécifier ils.
  • La notation littérale d'objet crée une instance d'objet que nous pouvons utiliser immédiatement. Avec la fonction, nous devrons peut-être d'abord créer son instance en utilisant l'opérateur new.
  • Également dans une approche littérale d'objet, nous pouvons explicitement ajouter des membres à un objet déjà défini à l'aide de l'opérateur dot. Cela est ajouté à l'instance spécifique uniquement. Cependant, j'ai ajouté une variable au prototype de fonction afin qu'elle se reflète dans toutes les instances de la fonction.

Ci-dessous J'ai essayé toutes les choses que nous avons faites avec Object et this ci-dessus, mais en créant d'abord une fonction au lieu d'écrire directement un objet.

/********************************************************************* 
  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. Lorsqu'il est utilisé dans la fonction constructeur.

Lorsque la fonction est utilisée comme constructeur (c'est-à-dire lorsqu'elle est appelée avec le mot-clé new), this dans le corps de la fonction pointe vers le nouvel objet en cours de construction.

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. Lorsqu'il est utilisé à l'intérieur de la fonction définie sur la chaîne prototype

Si le la méthode est sur la chaîne prototype d'un objet, this à l'intérieur de cette méthode fait référence à l'objet sur lequel la méthode a été appelée, comme si la méthode était définie sur l'objet.

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. Dans les fonctions call(), apply() et bind ()

  • Toutes ces méthodes sont définies sur Function.prototype.
  • Ces méthodes permettent d'écrire une fonction une fois et de l'invoquer dans un contexte différent. En d'autres termes, ils permettent de spécifier la valeur de this qui sera utilisée alors que la fonction est en cours d'exécution. Ils prennent également des paramètres à passer à la fonction d'origine lorsqu'elle est invoquée.
  • fun.apply(obj1 [, argsArray]) Ensembles de obj1, comme la valeur de this dans fun() et appels fun() passage d'éléments de argsArray comme arguments.
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Ensembles de obj1, comme la valeur de this dans fun() et appels fun() passage de arg1, arg2, arg3, ... comme arguments.
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Renvoie la référence à la fonction fun avec this à l'intérieur de plaisir lié à obj1 et les paramètres de fun liés aux paramètres spécifiés arg1, arg2, arg3,....
  • maintenant la différence entre apply, call et bind est devenue apparente. apply permet de spécifier les arguments pour fonctionner comme un objet de type tableau, c'est-à-dire un objet avec une propriété numérique length et des propriétés entières non négatives correspondantes. Alors que call permet de spécifier directement les arguments de la fonction. apply et call appellent immédiatement la fonction dans le contexte spécifié et avec les arguments spécifiés. D'autre part, bind renvoie simplement la fonction liée à la valeur this spécifiée et les arguments. Nous pouvons capturer la référence à cette fonction retournée en l'assignant à une variable et plus tard, nous pouvons l'appeler à tout moment.
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. {[12] } dans les gestionnaires d'événements

  • Lorsque vous affectez une fonction directement aux gestionnaires d'événements d'un élément, l'utilisation de this directement dans la fonction de gestion d'événements fait référence à élément correspondant. Une telle affectation directe de fonction peut être effectuée en utilisant la méthode addeventListener ou en utilisant les méthodes traditionnelles d'enregistrement d'événements comme onclick.
  • De même, lorsque vous utilisez this directement dans la propriété event (comme <button onclick="...this..." >) de l'élément, il fait référence à l'élément.
  • Cependant, l'utilisation de this indirectement via l'autre fonction appelée à l'intérieur de la fonction de gestion des événements ou de la propriété event résout l'objet global window.
  • La même chose ci-dessus le comportement est atteint lorsque nous attachons la fonction au gestionnaire d'événements à l'aide de la méthode de modèle d'enregistrement d'événements de Microsoft attachEvent. Au lieu d'affecter la fonction au gestionnaire d'événements (et à la méthode function de l'élément), elle appelle la fonction sur l'événement (l'appelant effectivement dans un contexte global).

Je recommande de mieux essayer ceci dans 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

Invocation de fonction simple

Considérons la fonction suivante:

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

Notez que nous l'exécutons en mode normal, c'est-à-dire que le mode strict n'est pas utilisé.

Lorsqu'il est exécuté dans un navigateur, la valeur de this serait connecté en tant que window. En effet, window est la variable globale dans la portée d'un navigateur Web.

Si vous exécutez ce même morceau de code dans un environnement comme le nœud.js, {[9] } ferait référence au global variable dans votre application.

Maintenant, si nous exécutons cela en mode strict en ajoutant l'instruction "use strict"; au début de la déclaration de fonction, this ne ferait plus référence à la variable globale dans l'un ou l'autre des environnements. Ceci est fait pour éviter les confusions dans le mode strict. this, dans ce cas il suffit de vous connecter undefined, parce que c'est ce qu'il est, il n'est pas défini.

Dans les cas suivants, nous verrons comment manipuler la valeur de this.

Appeler une fonction sur un objet

Il y a différentes façons de le faire. Si vous avez appelé des méthodes natives en Javascript comme forEach et slice, vous devez déjà savoir que la variable this dans ce cas fait référence au Object sur lequel vous avez appelé cette fonction (Notez qu'en javascript, à peu près tout est un Object, y compris Arrays et Function s). Prenez le code suivant par exemple.

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

Si un Object contient une propriété qui contient un Function, la propriété est appelée méthode. Ce la méthode, lorsqu'elle est appelée, aura toujours sa variable this définie sur Object à laquelle elle est associée. Cela est vrai pour les modes stricts et non stricts.

Notez que si une méthode est stockée (ou plutôt copiée) dans une autre variable, la référence à this n'est plus conservée dans la nouvelle variable. Par exemple:

// continuing with the previous code snippet

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

Considérant un scénario plus généralement pratique:

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

Le mot-clé new

Considérons une fonction constructeur dans 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`

, Comment cela fonctionne? Eh bien, voyons ce qui se passe lorsque nous utilisons le mot-clé new.

  1. Appeler la fonction avec le mot-clé new initialiserait immédiatement un Object de type Person.
  2. Le constructeur de ce Object a son constructeur défini sur Person. Notez également que typeof awal ne renverrait que Object.
  3. Ce nouveau Object se verrait attribuer le protoype de Person.prototype. Cela signifie que toute méthode ou propriété dans le Person le prototype serait disponible pour toutes les instances de Person, y compris awal.
  4. La fonction Person elle-même est maintenant invoquée; this étant une référence à l'objet nouvellement construit awal.

Assez direct, hein?

Notez que la spécification officielle ECMAScript no where indique que ces types de fonctions sont des fonctions réelles constructor. Ce ne sont que des fonctions normales, et new peut être utilisé sur n'importe quelle fonction. C'est juste que nous les utilisons comme tels, et donc nous appelons comme tel seulement.

L'Appel de fonctions sur les Fonctions : call et apply

Donc oui, puisque functions sont aussi Objects (et en fait des variables de première classe en Javascript), même les fonctions ont des méthodes qui le sont... ainsi, les fonctions themselved.

Toutes les fonctions héritent du Function global, et deux de ses nombreuses méthodes sont call et apply, et les deux peuvent être utilisées pour manipuler la valeur de this dans la fonction sur laquelle elles sont appelées.

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

C'est un exemple typique d'utilisation de call. Il prend essentiellement le premier paramètre et définit this dans la fonction foo comme référence à thisArg. Tous les autres paramètres passés à call sont passés à la fonction foo comme arguments.
Ainsi, le code ci-dessus enregistrera {myObj: "is cool"}, [1, 2, 3] dans la console. Très jolie façon de changer la valeur de this dans n'importe quelle fonction.

apply est presque le même que call accepter que cela ne prend que deux paramètres: thisArg et un tableau qui contient les arguments passés à la fonction. Donc, l'appel call ci-dessus peut être traduit en apply comme ceci:

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

Notez que call et apply peuvent remplacer la valeur de this définie par l'invocation de la méthode dot dont nous avons discuté dans la deuxième puce. Assez simple:)

Présentation.... bind!

bind il est le frère de call et apply. C'est aussi une méthode héritée par toutes les fonctions du constructeur global Function en Javascript. La différence entre bind et call/apply c'est que les deux call et apply invoqueront réellement la fonction. bind, d'autre part, renvoie une nouvelle fonction avec la thisArg et arguments pré-défini. Prenons un exemple pour mieux comprendre ceci:

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]`

Voyez la différence entre les trois? C'est subtil, mais ils sont utilisés différemment. Comme call et apply, bind dépassera également la valeur de this définie par l'invocation de la méthode dot.

Notez également qu'aucune de ces trois fonctions ne modifie la fonction d'origine. call et apply renverraient la valeur des fonctions fraîchement construites tandis que bind renverraient la fonction fraîchement construite elle-même, prête à être appelée.

Trucs supplémentaires, copiez ceci

Parfois, vous n'aimez pas le fait que this change avec l'étendue, spécialement imbriquée portée. Jetez un oeil à l'exemple suivant.

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"
        });
    }
  };

Dans le code ci-dessus, nous voyons que la valeur de this a changé avec la portée imbriquée, mais nous voulions la valeur de this de l'original portée. Nous avons donc 'copié' this vers that et utilisé la copie au lieu de this. Intelligent, hein?

Index:

  1. Qu'est-ce qui est maintenu dans this par défaut?
  2. Et si nous appelons la fonction comme une méthode avec la notation Objet-point?
  3. et si nous utilisons le new clé?
  4. Comment nous manipuler this avec call et apply?
  5. En utilisant bind.
  6. Copier this pour résoudre les problèmes de portée imbriquée.
 49
Author: Awal Garg, 2014-10-27 09:40:54

" ceci " est une question de portée. Chaque fonction a sa propre portée, et puisque tout dans JS est un objet, même une fonction peut stocker certaines valeurs en elle-même en utilisant "this". OOP 101 enseigne que "ceci" n'est applicable qu'aux instances d'un objet. Par conséquent, chaque fois qu'une fonction s'exécute, une nouvelle "instance" de cette fonction a une signification nouvelle de "ce".

La plupart des gens sont confus quand ils essaient d'utiliser "this" à l'intérieur des fonctions de fermeture anonymes comme:

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

Donc ici, dans each (), "this" ne contient pas la" valeur " à laquelle vous vous attendez (à partir de

this.value = value;
au-dessus). Donc, pour surmonter ce problème (sans jeu de mots), un développeur pourrait:
(function(value) {
    var self = this;            // small change
    self.value = value;
    $('.some-elements').each(function(elt){
        elt.innerHTML = self.value;        // phew!! == 2 
    });
})(2);

Essayez-le; vous commencerez à aimer ce modèle de programmation

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

this en Javascript se réfère toujours à la "propriétaire" de la fonction exécutée.

Si aucun propriétaire explicite n'est défini, alors le propriétaire le plus élevé, l'objet window, est référencé.

Donc si je l'ai fait

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

element.onclick = someKindOfFunction;

this ferait référence à l'élément de l'objet. Mais attention, beaucoup de gens font cette erreur

<element onclick="someKindOfFunction()">

Dans ce dernier cas, vous référencez simplement la fonction, pas la remettez à l'élément. Par conséquent, this reportez-vous à la fenêtre de l'objet.

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

Depuis que ce fil s'est cogné, j'ai compilé quelques points pour les lecteurs nouveaux sur le sujet this.

Comment la valeur de this est-elle déterminée?

Nous utilisons cela de la même manière que nous utilisons les pronoms dans les langues naturelles comme l'anglais: "John court vite parce que il essaie d'attraper le train."Au lieu de cela, nous aurions pu écrire "... Jean essaie d'attraper le train".

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 n'est pas affecté à une valeur jusqu'à ce qu'un objet appelle la fonction où il est défini. Dans la portée globale, toutes les variables et fonctions globales sont définies sur l'objet window. Par conséquent, this dans une fonction globale fait référence à (et a la valeur de) l'objet global window.

Quand use strict, this dans les fonctions globales et anonymes qui ne sont liées à aucun objet contient une valeur de undefined.

Le this le mot clé est de plus mal lorsque: 1) nous empruntons une méthode qui utilise this, 2) nous attribuez une méthode qui utilise this à une variable, 3) une fonction qui utilise this est passée en tant que fonction de rappel, et 4) this est utilisé dans une fermeture - une fonction interne. (2)

table

Ce qui réserve l'avenir

Défini dans ECMA Script 6 , les fonctions arrow adoptent la liaison this de la englobant la portée (fonction ou globale).

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!

Bien que les fonctions arrow fournissent une alternative à l'utilisation de bind(), il est important de noter qu'elles essentiellement désactivent le mécanisme traditionnel this en faveur d'une portée lexicale plus largement comprise. (1)


Références:

  1. Il s'agit d'un prototype d'objet, réalisé par Kyle Simpson. © 2014 Getify Solutions.
  2. javascriptissexy.com - http://goo.gl/pvl0GX
  3. Angus Croll - http://goo.gl/Z2RacU
 14
Author: carlodurso, 2014-10-30 03:58:06

Tous les function contexte d'exécution dans le code javascript a un portée contexte ce paramètre est défini par:

  1. Comment la fonction est appelée (y compris comme une méthode de l'objet, l'utilisation de appel de et appliquer, l'utilisation de nouveaux)
  2. Utilisation de bind
  3. Lexiquement pour les fonctions arrow (elles adoptent le this de leur contexte d'exécution externe)

Quel que soit ce contexte de portée, est référencé par "cela".

Vous pouvez changement que définir la valeur de ce portée contexte à l'aide de func.call, func.apply ou func.bind.

Par défaut, et ce qui confond la plupart des débutants, lorsqu'un callback listener est appelé après qu'un événement a été déclenché sur un élément DOM, le contexte de portée cette valeur de la fonction est l'élément DOM.

JQuery rend cela trivial à changer avec jQuery.proxy.

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

Ici est une bonne source de this dans JavaScript.

Voici le résumé:

  • Mondial cette

    Dans un navigateur, à la portée globale, this est le windowobject

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

    Dans node en utilisant le repl, this est l'espace de noms supérieur. Vous pouvez vous y référer comme global.

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

    Dans l'exécution de node à partir d'un script, this à la portée globale commence comme un objet vide. Il n'est pas le même que global

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

Sauf dans le cas des gestionnaires d'événements DOM ou lorsqu'un thisArg est fourni (voir plus bas), à la fois dans node et dans un navigateur utilisant this dans une fonction qui n'est pas appelée avec new fait référence à la portée 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>

Si vous utilisez use strict;, dans ce cas, this sera 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>

Si vous appelez une fonction de new le this sera un nouveau contexte, il ne sera pas référence mondiale 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>
  • prototype de cette

Les fonctions que vous créez deviennent des objets de fonction. Ils obtiennent automatiquement une propriété spéciale prototype, à laquelle vous pouvez attribuer des valeurs. Lorsque vous créez une instance en appelant votre fonction avec new, vous avez accès aux valeurs que vous avez affectées à la propriété prototype. Vous accédez à ces valeurs en utilisant this.

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

Thing.prototype.foo = "bar";

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

C'est une erreur d'attribuer tableaux ou objets sur l' prototype. Si vous voulez que les instances aient chacune leurs propres tableaux, créez-les dans la fonction, pas dans le prototype.

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 []
  • l'objet de cette

Vous pouvez utiliser this dans n'importe quelle fonction sur un objet pour se référer à d'autres propriétés de l'objet. Ce n'est pas la même chose qu'une instance créée avec new.

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

obj.logFoo(); //logs "bar"
  • DOM événement ce

Dans un gestionnaire d'événements DOM HTML, this est toujours une référence à l'élément DOM de l'événement attaché à

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

, Sauf si vous bind le contexte

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 ceci

Dans les attributs HTML dans lesquels vous pouvez mettre JavaScript, this est une référence à l'élément.

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

Vous pouvez utiliser eval pour l'accès this.

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

var thing = new Thing();
thing.logFoo();
  • avec ce

Vous pouvez utiliser with pour ajouter this à la portée actuelle pour lire et écrire dans des valeurs sur this sans se référer explicitement à 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 ce

Le jQuery aura dans de nombreux endroits this se référer à un élément 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, explication géniale! Quelques mots sur cela et une bonne liste de this pointeur de contexte d'exécution en cas de gestionnaires d'événements.

En deux mots, this en JavaScript pointe l'objet à partir duquel (ou à partir du contexte d'exécution duquel) la fonction actuelle a été exécutée et elle est toujours en lecture seule, vous ne pouvez pas la définir de toute façon (une telle tentative se terminera par un message 'Invalid left-hand side in assignment'.

Pour les gestionnaires d'événements: inline gestionnaires d'événements, tels que <element onclick="foo">, remplacez tous les autres gestionnaires attachés plus tôt et avant, alors soyez prudent et il est préférable de rester en dehors de la délégation d'événements en ligne. Et merci à Zara Alaverdyan qui m'a inspiré cette liste d'exemples à travers un débat dissident:)

  • 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

Il y a beaucoup de confusion quant à la façon dont "this" keyword est interprété en JavaScript. Espérons que cet article mettra tous ceux de se reposer une fois pour toutes. Et beaucoup plus. Veuillez lire l'intégralité de l'article avec attention. Soyez averti que cet article est long.

Quel que soit le contexte dans lequel il est utilisé, ,"cela" toujours les références de la "actuelle de l'objet" en Javascript. Cependant, ce que "objet courant" est différent selon contexte. Le contexte peut être exactement 1 de la 6 suivante:

  1. Mondiale (c'est à dire en Dehors de toutes les fonctions)
  2. Dans l'appel direct "Fonction Non liée" (c'est-à-dire une fonction qui a pas été lié en appelant functionName.lier)
  3. Dans l'appel Indirect "Fonction Non Liée" à travers functionName.appel et functionName.appliquer
  4. À l'intérieur de la "Fonction liée", Appelez (c'est-à-dire une fonction qui a été liée en appelant functionName.lier)
  5. Alors que la création d'objet par "nouveau"
  6. à l'Intérieur Inline DOM gestionnaire d'événement

Ce qui suit décrit chacun de ces contextes un par un:

  1. Contexte global (c'est-à-dire en dehors de toutes les fonctions):

    Extérieur toutes les fonctions (c'est-à-dire dans un contexte global) le "courant objet" (et donc la valeur de ,"cela") est toujours la "fenêtre" objet pour les navigateurs.

  2. À l'intérieur de l'appel direct "Fonction Non liée" :

    Dans un Appel direct "Fonction Non Liée", l'objet qui invoqué l'appel de fonction devient l ' "objet courant" (et donc la valeur de ,"cela"). Si une fonction est appelée sans un courant explicite objet, le actuelle de l'objet est le "fenêtre" objet (Pour les Non Mode Strict) ou undefined (Pour le Mode Strict) . Toute fonction (ou variable) définie dans Le contexte global devient automatiquement une propriété de l'objet "window".Par exemple, supposons que la fonction soit définie dans un contexte global comme

    function UserDefinedFunction(){
        alert(this)
        }
    

    Il devient la propriété de l'objet window, comme si vous aviez défini comme

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

    En "Mode Non Strict", Appelant / Appelant cette fonction directement via "UserDefinedFunction ()" {[11] } appellera/invoquera automatiquement il comme " fenêtre.UserDefinedFunction()" faire "fenêtre", comme l' "actuelle de l'objet" (et donc la valeur de ,"cela") dans "UserDefinedFunction".L'appel de cette fonction en "Mode Non Strict" entraînera ce qui suit

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

    En" Mode Strict", Appeler / Invoquer la fonction directement via "UserDefinedFunction()" "PAS" automatiquement appeler/invoquer comme "fenêtre.UserDefinedFunction ()".D'où le "courant objet" (et la valeur de ,"cela") dans "UserDefinedFunction"doit être undefined. L'appel de cette fonction en "Mode Strict" entraînera ce qui suit

    UserDefinedFunction() // displays undefined
    

    Cependant, l'invoquer explicitement à l'aide de l'objet window entraînera ce qui suit

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

    Regardons un autre exemple. Veuillez regarder ce qui suit code

     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
    

    Dans l'exemple ci-dessus, nous voyons que lorsque "UserDefinedFunction" et invoquée par o1, "cette" prend la valeur de o1, et les la valeur de ses propriétés "a" et "b" s'affiche. Valeur de "c" et "d" ont montré que undefined, comme o1 ne ne pas définir ces propriétés

    De même lorsque "UserDefinedFunction" a été invoqué par o2, ,"cela" prend la valeur de o2 et la valeur de ses propriétés "c" et "d" s'affiche.La valeur de "a" et "b" ont montré que undefined, comme o2 ne définit pas ces propriétés.

  3. À l'intérieur Indirect "Fonction Non liée" Appel par functionName.appel et functionName.appliquer:

    Quand un " Non lié La fonction " est appelée par functionName.appel ou functionName.appliquer, le "actuelle de l'objet" (et donc la valeur de ,"cela") est définie à la valeur de ,"cela" paramètre (premier paramètre) passé à appel/s'appliquent. Le code suivant démontre la même chose.

    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
    

    Le code ci-dessus montre clairement que la valeur "this" pour tout " NON Fonction liée " peut être modifiée par call/apply . Aussi,si l' ,"cela" paramètre n'est pas explicitement transmis à appeler/appliquer, "actuelle de l'objet" (et donc la valeur de "ce") est réglée sur "fenêtre" Non en mode strict et "undefined" en mode strict.

  4. À l'intérieur de l'appel" Bound Function " (c'est-à-dire une fonction qui a été liée en appelant functionName.lier):

    Une fonction liée est une fonction dont la valeur "this" a été fixe. Le code suivant a démontré comment "this" fonctionne au cas où de la fonction liée

    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
    

    Comme indiqué dans le code ci-dessus, "cette" valeur pour toute " Fonction liée" NE PEUT PAS être modifié via call / apply. De plus, si le "this" paramètre n'est pas explicitement transmis à lier, "actuelle de l'objet" (et donc la valeur de ,"cela" ) est mis à "fenêtre" Non le mode strict et "undefined" en mode strict. Une chose de plus. La liaison d'un déjà lié fonction ne change pas la valeur de ,"cela". Il reste que la valeur définie par la première fonction de liaison.

  5. Alors que la création d'objet par "nouveau":

    Dans une fonction constructeur, le "objet courant" (et donc la valeur de "this") fait référence à l'objet en cours de création par "nouveau" indépendamment du statut de liaison de la fonction. Cependant si le constructeur est une fonction liée il doit être appelé avec ensemble prédéfini d'arguments comme défini pour la fonction liée.

  6. À l'Intérieur Inline DOM gestionnaire d'événement:

    Veuillez regarder l'extrait HTML suivant

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

    Le"this" dans les exemples ci-dessus se réfèrent à l'élément "button" et au élément " div " respectivement.

    Dans le premier exemple, la couleur de police du bouton doit être définie sur blanc quand il est cliqué.

    Dans le deuxième exemple lorsque le "div" l'élément est cliqué il doit appelez la fonction OnDivClick avec son deuxième paramètre référencement de l'élément div cliqué. Cependant, la valeur de ,"cela" dans OnDivClick NE DOIT PAS faire référence au div cliqué élément. Il doit être défini comme "objet fenêtre" ou "undefined" dans Non stricte et Stricte Modes de, respectivement (si OnDivClick est un indépendant de la fonction) ou de l'ensemble d'un modèle prédéfini Lier valeur (si OnDivClick est un lié fonction)

Ce qui suit résume l'article entier

  1. Dans un Contexte Global ,"cela" renvoie toujours à la "fenêtre" object

  2. Chaque fois qu'une fonction est appelée, elle est invoquée dans le contexte d'une objet ("objet courant"). Si l'objet courant n'est pas explicitement fourni, l'objet courant est la fenêtre " objet " dans NON strict Mode et "undefined" en mode Strict par défaut.

  3. La valeur de ,"cela" dans un pays Non Lié fonction est la référence à l'objet dans le cadre de laquelle la fonction est invoquée ("de l'objet courant")

  4. La valeur de "this" dans une fonction non liée peut être remplacée par appel de et appliquer méthodes de la fonction.

  5. La valeur de "this" est fixé pour une fonction Liée et ne peut pas être remplacé par appel de et appliquer méthodes de la fonction.

  6. La fonction de liaison et déjà liée ne change pas la valeur de "this". Il reste que la valeur définie par la première fonction de liaison.

  7. La valeur de ,"cela" sein d'un constructeur est l'objet qui est créé et initialisé

  8. La valeur de ,"cela" dans une ligne DOM gestionnaire d'événement de référence à l'élément pour lequel le gestionnaire d'événements est donné.

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

Probablement l'article le plus détaillé et le plus complet sur this est le suivant:

Explication douce du mot-clé "this" en JavaScript

L'idée derrière this est de comprendre que les types d'invocation de fonction ont l'importance significative sur la définition de la valeur this.


En cas de problèmes d'identification this, ne vous demandez pas :

Où est this prises à partir de?

Mais faire demander vous-même:

Comment la fonction est-elle invoquée?

Pour une fonction de flèche (cas particulier de transparence de contexte) demandez-vous:

Quelle valeur a thisoù la fonction flèche est définie?

Cet état d'esprit est correct lorsqu'il s'agit de this et vous évitera des maux de tête.

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

C'est la meilleure explication que j'ai vue. Comprendre les JavaScripts ce avec Clarté

Lecette référence fait TOUJOURS référence à (et contient la valeur de) un objet-un objet singulier-et il est généralement utilisé à l'intérieur d'une fonction ou d'un la méthode, bien qu'elle puisse être utilisée en dehors d'une fonction dans le global portée. Notez que lorsque nous utilisons le mode strict, cela contient la valeur de indéfini dans les fonctions globales et dans les fonctions anonymes qui ne le sont pas lié à tout objet.

Il y a Quatre conditions où ce peut prêter à confusion:

  1. Lorsque nous passons une méthode (qui utilise this ) comme paramètre à utiliser comme fonction de rappel.
  2. Un autre cas où cela est mal compris est lorsque nous utilisons une méthode interne (une fermeture). Il est important de noter que les fermetures ne peuvent pas accéder à la variable this de la fonction externe en utilisant le mot clé this car la variable this n'est accessible que par la fonction lui-même, pas par des fonctions intérieures.
  3. Utiliser ce lorsqu'une méthode est affectée à une variable. La valeur this est liée à un autre objet, si nous affectons une méthode qui l'utilise à une variable
  4. En utilisant ce lors de l'utilisation des méthodes bind, apply et call.

Il donne des exemples de code, les explications et les corrections de code que je pensais très utiles.

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

Il est difficile d'avoir une bonne compréhension de JS, ou d'écrire plus que tout ce qui est trivial, si vous ne le comprenez pas bien. Vous ne pouvez pas vous permettre de faire un plongeon rapide:) Je pense que la meilleure façon de commencer avec JS est de regarder d'abord ces conférences vidéo de Douglas Crockford - http://yuiblog.com/crockford / , qui couvre ceci et cela, et tout le reste sur JS.

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

En termes pseudoclassiques, la façon dont de nombreuses conférences enseignent le mot-clé "this" est comme un objet instancié par un constructeur de classe ou d'objet. Chaque fois qu'un nouvel objet est construit à partir d'une classe, imaginez que sous le capot une instance locale d'un objet "this" est créée et renvoyée. Je me souviens qu'il a enseigné comme ceci:

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 est l'un des concepts mal compris en JavaScript car il se comporte peu différemment d'un endroit à l'autre. Simplement, this fait référence au "propriétaire" de la fonction que nous exécutons actuellement.

this aide à obtenir l'objet actuel (alias contexte d'exécution) avec lequel nous travaillons. Si vous comprenez dans quel objet la fonction actuelle est exécutée, vous pouvez facilement comprendre ce que this est

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

Ci-dessus, nous créons 3 variables avec le même nom 'val'. L'un dans le contexte global, l'un à l'intérieur d'obj et l'autre à l'intérieur de la méthode d'obj. JavaScript résout les identificateurs dans un contexte particulier, en remontant la chaîne d'étendue locale globale.


Peu d'endroits où this peuvent être différenciées

Appeler une méthode d'un objet

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

Lorsque line1 est exécuté, JavaScript établit un contexte d'exécution (EC) pour l'appel de fonction, en définissant this sur l'objet référencé par whatever came avant le dernier ".". ainsi, dans la dernière ligne, vous pouvez comprendre qu' a(), a été exécuté dans le contexte global qui est le window.

Avec le constructeur

this peut être utilisé pour faire référence à l'objet créé

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

Lorsque new Person() est exécuté, un objet complètement nouveau est créé. Person est appelé et son this est défini pour référencer ce nouvel objet.

Appel de Fonction

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 

Si nous manquons le mot-clé new, whatIsThis fait référence au plus global contexte il peut trouver(window)

Avec les gestionnaires d'événements

Si le gestionnaire d'événements est en ligne, this fait référence à l'objet global

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

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

Lors de l'ajout d'un gestionnaire d'événements via JavaScript, this fait référence à l'élément DOM qui a généré l'événement.


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

La valeur de "ce" dépend du "contexte" dans lequel la fonction est exécutée. Le contexte peut être n'importe quel objet ou l'objet global, c'est-à-dire la fenêtre.

Donc la sémantique de "ceci" est différente des langues traditionnelles de POO. Et cela cause des problèmes: 1. lorsqu'une fonction est passée à une autre variable( très probablement, un rappel); et 2. lorsqu'une fermeture est invoquée à partir d'une méthode membre d'une classe.

Dans les deux cas, cette valeur est définie sur window.

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

Devait ce aider? (La plus grande confusion de "this" en javascript vient du fait qu'il n'est généralement pas lié à votre objet , mais à la portée d'exécution actuelle that ce n'est peut-être pas exactement comment cela fonctionne mais c'est toujours comme ça pour moi see voir l'article pour une explication complète)

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

Un peu d'informations sur ce mot-clé

Enregistrons le mot-clé this dans la console dans la portée globale sans plus de code mais

console.log(this)

Dans Client/Navigateur this mot-clé est un objet global qui est window

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

Et

Dans Serveur/Node/runtime Javascript this mot-clé est également un objet global qui est module.exports

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

Gardez à l'esprit exports est juste une référence à module.exports

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

Cette utilisation pour la portée comme ceci

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

La valeur de txt1 et txt est identique dans l'exemple ci-Dessus $(this)=(('#tbleName tbody tr') est identique

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

Résumé this Javascript:

  • La valeur de thisest déterminée par comment la fonction n'est pas invoquée, où elle a été créée!
  • Habituellement, la valeur de this est déterminée par l'objet qui est à gauche du point. (window dans l'espace global)
  • Dans les écouteurs d'événements, la valeur de this fait référence à l'élément DOM sur lequel l'événement a été appelé.
  • Lorsque la fonction in est appelée avec le mot-clé new, la valeur de this fait référence à la nouvelle création objet
  • , Vous pouvez manipuler la valeur de this, avec les fonctions: call, apply, bind

Exemple:

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
              
             

Exemple d'écouteurs d'événement:

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>

Exemple de constructeur:

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