Est-ce que window est vraiment global en Javascript?
prenez ce morceau de Javascript dans un navigateur:
<script>
console.log(window.someThing);
var x = 12;
function foo() {
window.otherThing = x;
}
</script>
à l'Intérieur foo
on peut y accéder window
, nous le savons tous, mais pourquoi exactement?
- c'Est une sorte de variable globale?
- ou le "root scope" (à l'intérieur du
script
tag) l'ont comme variable locale implicite et est-il simplement "closure-inherited" comme toute autre variable locale (commex
ci-dessus) peut être?
Et comment en accord avec les variables déclarés directement à l'intérieur de l' script
balise est définie comme propriétés de window
? (Ou bien est-ce pas?)
<script>
var x = 12;
function() {
console.log(window.x);
}
</script>
7 réponses
La raison pour laquelle vous pouvez accéder à "hors de portée" ou "libre" les variables en ECMAscript sont les telles appelées Champ d'application de la chaîne. La chaîne scope est une propriété spéciale de chaque contexte d'Exécution. Comme mentionné plusieurs fois auparavant, un objet contextuel ressemble au moins à:
- [[portée]]
- Variable / Activation De L'Objet
- "ce" contexte de la valeur
chaque fois que vous accédez à un variable (- name) dans un contexte (une fonction par exemple), le processus de recherche démarre toujours dans son propre Activation Object
. Tous les paramètres formels, les déclarations de fonction et les variables définies localement (var) sont stockés dans cet objet spécial. Si le variablename n'a pas été trouvé dans cet objet, la recherche va dans le [[Scope]]
chaîne. Chaque fois qu'une fonction(-context) est initialisée, elle copie tout parent variable de contexte/les objets d'activation en interne [[Scope]]
propriété. C'est ce que nous appel, un portée lexicale. C'est la raison pour laquelle Fermetures travailler en ECMAscript. Depuis l' Global context
a aussi un Variable Object
(plus précisément, **la variable de l'objet pour l'objet global est l'objet global), on obtient également copiés dans les fonctions [[Portée]] propriété.
C'est la raison pour laquelle vous pouvez accéder à window
à partir de l'intérieur de n'importe quelle fonction :-)
l'explication ci-dessus a une conclusion conceptuelle importante: toute la fonction en ECMAscript est un Fermeture, ce qui est vrai. Puisque chaque fonction copiera au moins le contexte global VO dans son [[Portée]] propriété.
est-ce que window est vraiment global en Javascript?
Oui. Sauf si vous créez une nouvelle variable appelée window dans une portée plus étroite
function foo() {
var window;
}
à l'intérieur de foo on peut accéder à window, on le sait tous, mais pourquoi exactement?
N'importe quelle fonction peut accéder à des variables déclarées dans une portée plus large. Il n'y a rien de spécial dans window there.
tout est défini en ECMAScript.
le global est un environnement Lexical qui n'a pas d'environnement lexical externe. Tous les autres environnements y sont imbriqués, et sont liés à un objet global avec des propriétés spécifiées par le spec.
cela place les propriétés de l'objet global au début de la chaîne scope, dont héritent tous les autres environnements.
:
le l'environnement global est un environnement Lexical unique qui est créé avant l'exécution de tout code ECMAScript. La fiche D'environnement de l'environnement global est une fiche d'environnement objet dont l'objet liant est l'objet global (15.1). La référence de l'environnement extérieur de l'environnement mondial est nulle.
lorsque le code ECMAScript est exécuté, des propriétés supplémentaires peuvent être ajoutées à l'objet global et les propriétés initiales peuvent être modifiées.
l'objet global unique est créé avant que le contrôle n'entre dans un contexte d'exécution.
sauf indication contraire, les propriétés standard intégrées de l'objet global ont des attributs {[Writable]]]: true, [[Enumerable]]: false, [[Configurable]]: true}.
l'objet global n'a pas de propriété interne [[Construct]]; il n'est pas possible d'utiliser l'objet global comme un constructeur avec le nouveau opérateur.
L'objet global ne dispose pas d'un [[]] propriété interne; il n'est pas possible d'invoquer l'objet global comme une fonction.
les valeurs des propriétés internes [[Prototype]] et [classe] de l'objet global dépendent de l'implémentation.
outre les propriétés définies dans cette spécification, l'objet global peut avoir d'autres hôte des propriétés définies. Cela peut inclure une propriété dont la valeur est l'objet global elle - même; par exemple, dans le modèle D'objet HTML document, la propriété window de l'objet global est l'objet global lui-même.
cela a à voir avec le champ d'application de la chaîne.
jetez un oeil à l' présentation de Nicholas C. Zakas. (à partir de min 5)--3-->
window est le champ d'application de base de tous les objets javascript, et il est automatiquement "attaché" à chaque variable que vous définissez, à moins que vous n'utilisiez "var" avant la déclaration, dans ce cas le champ d'application de la variable c'est local (cela signifie qu'il est contenu dans la fonction mère, ou est aussi global, si vous déclarez votre variable en dehors d'un bloc de fonctions). En outre la fenêtre est définie comme une constante, c'est vous ne pouvez pas redéfinir l'objet window (vous obtenez un message d'erreur disant "erreur de type: redeclaration de const fenêtre").
donc:
window.foo = 5;
c'est la même chose que:
var foo = 5;
ou:
function() {
foo = 5;
}
mais:
function() {
var foo = 5;
}
dans ce cas, "foo" est locale (fenêtre.foo = = = Non défini)
window
global scope s'applique uniquement au fil principal. Dans les travailleurs du web il n'y a pas de window
variable globale. Au lieu de cela, vous avez WorkerGlobalScope
dans un WebWorker
et SharedWorkerGlobalScope
dans un SharedWorker
.
ce worker global scope est stocké dans une variable appelée self
et comme MDN décrit:
ce champ contient les informations habituellement véhiculée par Fenêtre objet.
cela peut devenir un problème lorsque le code tiers que vous utilisez dans votre Web worker utilise l'objet window. Ceci peut être facilement résolu en déclarant un window
variable comme suggéré par @FelipeMicaroniLalli dans réponse ici comme ceci:
var window = self;
Dans le livre Javascript: Les Bonnes Parties, ce que je comprends, Douglas Crockford explique que window
est l'objet global du navigateur web qui contient toutes les variables globales. C'est comme l'Anneau unique...