`This` dans la portée globale dans ECMAScript 6

J'ai essayé de regarder dans le projet ES6 moi-même, mais je ne sais pas où chercher:

Quelqu'un peut-il me dire si this dans ES6 fait nécessairement référence à l'objet global? De même, cet objet aura-t-il les mêmes membres que la portée globale?

Si vous pouviez répondre pour ES5 qui serait également utile.

Je sais que this dans la portée globale se réfère à l'objet global dans le navigateur et dans la plupart des autres environnements ES, comme Node. Je veux simplement savoir si c'est le comportement défini par la spécification ou si c'est un comportement étendu que les implémenteurs ont ajouté (et si ce comportement continuera dans les implémentations ES6). En outre, l'objet global est-il toujours le même que la portée globale? Ou y a-t-il des distinctions?


Mise à jour – Pourquoi je veux savoir: je cherche essentiellement à comprendre comment obtenir l'objet global de manière fiable dans ES5 et 6. Je ne peux pas compter sur la window car c'est spécifique au navigateur, et je ne peux pas compter sur le global car c'est précis À des environnements comme Node. Je sais que this dans Node peut se référer au module dans la portée du module, mais je pense qu'il se réfère toujours à une portée global sur le plan mondial. Je souhaite un moyen compatible avec ES5 et 6 pour obtenir l'objet global (si possible). Il semble que dans tous les environnements que je connaisse de this dans le cadre global, mais je veux savoir si cela fait partie des spécifications réelles (et donc fiables dans tout environnement dont je ne connais pas peut-être).

Je dois également savoir si la portée globale et l'objet global sont identiques. En d'autres termes, toutes les variables dans la portée globale seront-elles identiques à globalobject.variable_name ?


Mise à jour 2 – Ce que j'essaie de faire:

J'ai développé des cales ES6 pour les environnements ES5 . Je souhaite connaître la meilleure façon de (1) vérifier si les ESL intégrés existent déjà afin qu'ils puissent être utilisés lorsque possible au lieu de mes cales, et (2) ajoute mes cales à la portée globale si le build- Les ins n'existent pas déjà.

Actuellement, je suis en train de suivre ce modèle:

 (function() { // Indirect eval to run in global scope. // (We get whatever "this" is in global scope, hoping that it's the global object... // Whether this line does what I want it to is the crux of my question.) var global = (0, eval)('this'); // If Symbol does not already exist in global scope, if (!global.Symbol) // Then add Symbol to global scope. global.Symbol = (function() { // ... // Return my Symbol shim })(); })(); 

Il existe d'autres possibilités pour (1), mais à la fin de la journée, j'ai besoin d'ajouter quelque chose à la portée mondiale sans utiliser var dans la portée mondiale (car cela éviterait les composants intégrés avant de pouvoir les vérifier, en raison À var hisser [au moins dans l'affaire naïve, peut-être que je pourrais indirectement eval une déclaration var aussi?]). Je veux que mon code puisse fonctionner en mode strict, de sorte que le problème soit complexe.

J'ai découvert que, par la spécification ES5, eval indirect exécute un code à l'échelle mondiale. Je suis donc au moins capable de le faire. Mes questions sont si j'obtiens this dans la portée globale, (1) Vérifie les propriétés de cet objet, faites-moi savoir si un système intégré existe déjà dans la portée mondiale? Et (2) L'ajout de propriétés à cet objet m'a-t-il permis d'ajouter des variables à la portée globale?

Oui, this dans le cadre global continuera à se référer à l'objet global dans ES6. (Généralement, ES6 est supposé être entièrement compatible avec l'arrière, c'est-à-dire que tout code qui devait fonctionner dans ES5 devrait également fonctionner dans ES6).

La notion de «portée globale», cependant, ne sera plus identique à l'objet global dans ES6. Il introduit de nouveaux formulaires de déclaration qui sont de portée lexique ( let , const , class , module et quelques autres). La conclusion à la dernière réunion était qu'aucun d'entre eux n'apparaît comme une propriété de l'objet global. Il existe une variété de raisons techniques et méthodologiques pour cela, mais en bout de ligne, il est préférable d'éviter complètement l'utilisation de l'objet global (cela a toujours été vrai, mais il en est de même dans ES6).

Y at-il quelque chose de spécifique dont vous avez besoin pour l'objet global?

Principalement oui.

Passer this dans un objet non objet (ou non défini) se référera à l'objet global:

 (function( global ){ /* do stuff! */ }(this)); 

Ce comportement est destiné à rester dans ES6 (pour des problèmes de compatibilité ascendante compréhensibles). Et c'est ainsi que la plupart des plugins multi-formes (Navigateur / Nœud) que je connais ont accès à l'objet global. Par exemple: https://github.com/documentcloud/underscore/blob/master/underscore.js#L12

Bien que, il est vrai que le plugin sur le serveur n'accepte que this comme module (qui est exporté). Mais, c'est ce que vous voulez dans le nœud. Votre espace global n'est jamais nettoyé (sauf s'il est effectué manuellement ou si le serveur est redémarré). Donc, il est partagé entre toutes les connexions client; Affecter n'importe quoi à l'espace global n'est vraiment pas une bonne idée.


La seule différence notable dans la façon dont this est géré entre javascript "version" est en strict mode , où il va lancer une erreur est si null ou undefined est passé à call ou apply ou bind (dans la position de this value ). En mode non strict, this n'a été forcé que pour l'objet global.

 "use strict"; foo.apply(null); // Throw error 

J'espère que cette aide!