Accéder à la propriété globale en utilisant le mot-clé "this" dans une fonction

Je sais que sous javascript, lorsque vous utilisez le mot-clé "this" dans une fonction, alors "this" renvoie au 'owner' de cette fonction en fonction du site Web Quirksmode . Par conséquent, lorsque nous avons une fonction et que nous utilisons "this" intérieur, alors "this" fait référence à l'objet global (fenêtre).

Je suis un peu confus sur la façon dont "this" fonctionne, par exemple dans le code ci-dessous, "this" devrait être capable de résoudre x puisque x est à peu près une propriété de l'objet global (dans cette fenêtre cas). Mais this.x dans ce cas, this.x "undefined" au lieu de la valeur x .

 var x = "Global"; function foo(){ alert(this.x); //undefined }; foo(); 

J'ai ensuite essayé d'autres choses aussi:

 function bar(){ function foo(){ alert(this); //[Object DOMWindow] }; foo(); }; bar(); 

Si ma compréhension est correcte, alors 'this' devrait se référer à la bar() dans ce second cas car c'est le propriétaire de foo() , mais pourquoi se réfère-t-il à l'objet global?

Quelqu'un peut-il expliquer quelle est la théorie correcte concernant le mot-clé "this"?

En résumant votre question, vous demandez pourquoi dans votre premier extrait, this.x est undefined :

 var x = "Global"; function foo(){ alert(this.x); //undefined } foo(); 

Ce n'est pas du tout logique, this valeur devrait se référer à l'objet global – si votre code était en mode strict, vous obtiendriez un TypeError , car this seul serait undefined .

La seule façon dont je pense que this.x pourrait être undefined , est dans le cas où la déclaration de variable de x été réalisée dans une fonction.

Vérifiez les deux exemples suivants: 1 et 2 , c'est exactement le même code, la différence est que le second, le code est enveloppé dans un gestionnaire d'événements en charge, de sorte que la variable x n'existe pas dans la portée globale ( window.x Est undefined ) …

Vous avez la mauvaise fin du bâton. La valeur de this dépend de la façon dont la fonction est appelée , et non pas comment elle est définie.

  • Si vous appelez window.foo() puis (inside foo), this sera une window
  • Si vous appelez bar.foo() this sera une bar (même si vous devez copier foo donc c'est une propriété de la bar premier)
  • Si vous appelez baz.bar.foo() this sera une bar (vous n'obtenez jamais l'objet parent via this )
  • Si vous appelez foo.call(bar) this sera également une bar comme call vous permet de remplacer this
  • Si vous appelez new foo() this sera le nouvel objet créé

L'objet par défaut est la window , donc, si vous appelez foo() alors c'est la même chose que window.foo() .

Peu importe la portée dans laquelle la fonction est définie.

Oui, c'est toujours le propriétaire de la fonction exécutée et la meilleure réponse à ce sujet est plus que ce que vous avez toujours voulu savoir à this sujet

 var x = "Global"; function foo(){ alert(this.x); // alerts "Global" for me }; 

En ce qui concerne la bar() , c'est une fonction autonome et this sera lié à l'objet "global" tel que décrit dans la réponse ci-dessus, c'est-à-dire le DOMWindow

Si vous souhaitez vraiment apprendre comment this fonctionne, lisez les spécifications ECMAscript 262 de la section 10.3 Execution Context et en avant.

Voici ce qu'il dit dans la section 10.4.3:

10.4.3 Saisie du code de fonction

Les étapes suivantes sont effectuées lorsque le contrôle entre dans le contexte d'exécution pour le code de fonction contenu dans l'objet fonction F, un appelant fourni thisArg et un appeler fourni argumentsList:

  1. Si le code de fonction est un code strict, définissez ThisBinding to thisArg.

  2. Sinon, si thisArg est nul ou indéfini, définissez ThisBinding sur l'objet global.

  3. Sinon, si Type (thisArg) n'est pas Object, définissez ThisBinding to ToObject (thisArg).

  4. Ensuite, définissez ThisBinding to thisArg.

  5. Laissez localEnv être le résultat de l'appel de NewDeclarativeEnvironment en passant la valeur de [[Scope]] propriété interne de F comme argument.

  6. Définissez LexicalEnvironment dans localEnv.

  7. Définissez l'environnement variable dans localEnv.

  8. Laissez le code être la valeur de la propriété interne [[Code]] de F.

  9. Exécutez l'Instanciation de liaison de déclaration en utilisant le code de code de fonction et les argumentsListe comme décrit dans 10.5.