web-dev-qa-db-fra.com

Pourquoi "ceci" dans une fonction anonyme n'est pas défini lors de l'utilisation stricte?

Pourquoi est-ce dans une fonction anonyme non défini lors de l'utilisation de javascript en mode strict? Je comprends pourquoi cela pourrait avoir un sens, mais je n'ai trouvé aucune réponse concrète.

Exemple:

(function () {
    "use strict";

    this.foo = "bar"; // *this* is undefined, why?
}());

Testez dans un violon: http://jsfiddle.net/Pyr5g/1/ Consultez l'enregistreur (firebug).

80
TJ.

C'est parce que, jusqu'à ECMAscript 262 édition 5, il y avait une grande confusion si les gens qui utilisaient le constructor pattern, j'ai oublié d'utiliser le mot clé new. Si vous avez oublié d'utiliser new lors de l'appel d'une fonction constructeur dans ES3, this a référencé l'objet global (window dans un navigateur) et vous assommeriez l'objet global avec des variables.

C'était un comportement horrible et les gens de l'ECMA ont donc décidé de régler this sur undefined.

Exemple:

function myConstructor() {
    this.a = 'foo';
    this.b = 'bar';
}

myInstance     = new myConstructor(); // all cool, all fine. a and b were created in a new local object
myBadInstance  = myConstructor(); // oh my gosh, we just created a, and b on the window object

La dernière ligne jetterait une erreur dans ES5 strict

"TypeError: this is undefined"

(ce qui est un bien meilleur comportement)

94
jAndy

Il existe un mécanisme appelé "boxing" qui encapsule ou modifie l'objet this avant d'entrer dans le contexte de la fonction appelée. Dans votre cas, la valeur de this doit être undefined car vous n'appelez pas la fonction comme méthode d'un objet. Si le mode n'est pas strict, dans ce cas, il est remplacé par l'objet window. En mode strict, il est toujours inchangé, c'est pourquoi c'est undefined ici.

Vous pouvez trouver plus d'informations sur
https://developer.mozilla.org/en/JavaScript/Strict_mode

15
Samuel Rossille

Selon This Stack Overflow answer , vous pouvez utiliser this à l'intérieur des fonctions anonymes, simplement en appelant .call(this) à la fin.

(function () {
    "use strict";

    this.foo = "bar";
}).call(this);
5
ReverseTales