2012-11-16 16 views
5

Ich habe versucht, in der ES6 suche mich Entwurf, aber ich bin mir nicht sicher, wo sie suchen:`this` in globalem Bereich in ECMAScript 6

Kann mir jemand sagen, ob this unbedingt in ES6 auf den globalen verweist Objekt? Verfügt dieses Objekt über dieselben Member wie den globalen Bereich?

Wenn Sie für ES5 antworten könnten, wäre das auch hilfreich.

Ich weiß, this im globalen Bereich bezieht sich auf das globale Objekt im Browser und in den meisten anderen ES-Umgebungen, wie Node. Ich möchte nur wissen, ob dies das definierte Verhalten der Spezifikation ist oder ob es sich um ein erweitertes Verhalten handelt, das die Implementierer hinzugefügt haben (und wenn dieses Verhalten in ES6-Implementierungen fortgesetzt wird). Ist das globale Objekt immer das gleiche wie der globale Bereich? Oder gibt es Unterschiede?


Update - Warum will ich wissen: Ich bin im Grunde genommen, um herauszufinden, wie das globale Objekt zuverlässig in ES5 & 6. Ich auf window verlassen kann nicht bekommen, weil das für den Browser ist, noch kann ich mich auf global verlassen, weil das spezifisch für Umgebungen wie Node ist. Ich weiß, this in Node kann auf module im Modul Bereich beziehen, aber ich denke, es bezieht sich immer noch auf global im globalen Umfang. Ich möchte eine Cross-Umwelt-ES5 & 6-konforme Möglichkeit, das globale Objekt (wenn möglich) zu erhalten. Es scheint, als ob in all den Umgebungen, die ich kenne von this im globalen Bereich, dass, aber ich möchte wissen, ob es Teil der eigentlichen Spezifikation ist (und so zuverlässig über jede Umgebung, die ich nicht vertraut sein kann).

Ich muss auch wissen, ob der globale Bereich und das globale Objekt die gleiche Sache von der Spezifikation sind. Mit anderen Worten sind alle Variablen im globalen Gültigkeitsbereich gleich globalobject.variable_name?


Update 2 - Was ich bin versucht:

Ich habe einige ES6 shims for ES5 environments entwickelt. Ich möchte den besten Weg kennen, um (1) zu prüfen, ob die ES6-Einbauten bereits existieren, so dass sie wenn möglich anstelle meiner Beilagen verwendet werden können, und (2) meine Unterlegscheiben dem globalen Umfang hinzuzufügen, wenn die eingebauten Ins existieren nicht schon.

Zur Zeit ist ich nach diesem Muster:

(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 

     })(); 

})(); 

Es gibt einige andere Möglichkeiten (1), aber am Ende des Tages ich einen Weg brauchen, um etwas zu globalen Bereich hinzuzufügen, ohne var in globale Reichweite (denn das würde die Einbauten außer Kraft setzen, bevor ich sie überprüfen können, aufgrund var Hebe [zumindest in der naiven Fall, vielleicht könnte ich indirekte eval eine var Aussage auch?]). Ich möchte, dass mein Code im strikten Modus ausgeführt werden kann, so dass das Problem zusammenhängt.

Ich habe entdeckt, dass durch die ES5 spec, indirekte eval Code in globalem Bereich ausführt. Das kann ich zumindest. Meine Fragen sind, wenn ich this in globalen Bereich zu erhalten, (1) Will die Überprüfung der Eigenschaften dieses Objekts lassen Sie mich wissen, ob ein Einbau-existiert bereits im globalen Bereich? und (2) Erlaubt das Hinzufügen von Eigenschaften zu diesem Objekt das Hinzufügen von Variablen zum globalen Bereich?

+3

Es sollte wie vorherige ES-Spezifikationen funktionieren, da "dies" nicht ES6-spezifisch ist. Die Bedeutung von "this" hängt davon ab, wo es verwendet wird, und ist nicht immer das globale Objekt. – Jay

+0

Verstanden; Deshalb habe ich "in globalem Umfang" gefragt, wo in Browsern "this" dasselbe ist wie "window", welches auch das globale Objekt ist. Ich weiß jedoch nicht, ob dies in ES angegeben ist oder ob es sich lediglich um eine Browser-Erweiterung der Sprache handelt. –

+1

Solange Sie nicht in etwas wie SES sind, wird der indirekte Evaluierungstrick zuverlässig funktionieren. Sobald Sie das globale Objekt haben, können Sie es zuweisen und Eigenschaften überprüfen und dies wird tun, was Sie wollen. In es6, jenseits dessen, was Andreas über let, const usw. gesagt hat, gibt es auch die Frage, ob Module ihr eigenes privates globales haben, das das globale Hauptobjekt als äußeren Geltungsbereich hat. Daher ist es unmöglich, auf das äußere globale Objekt zuzugreifen oder es zu modifizieren Es wird zur Verfügung gestellt (wie node.js zum Beispiel "global" automatisch definieren, würde Ihnen einen Verweis auf diese äußere globale geben). –

Antwort

2

Ja, this im globalen Gültigkeitsbereich wird sich weiterhin auf das globale Objekt in ES6 beziehen. (Im Allgemeinen sollte ES6 vollständig abwärtskompatibel sein, d. H. Jeder Code, der garantiert in ES5 funktioniert, sollte auch in ES6 funktionieren).

Der Begriff "globaler Gültigkeitsbereich" ist jedoch nicht mehr identisch mit dem globalen Objekt in ES6. Es führt neue Deklarationsformulare ein, die lexikalisch begrenzt sind (let, const, class, module und einige mehr). Die Schlussfolgerung auf der letzten Sitzung war, dass keine davon als Eigenschaften des globalen Objekts erscheinen wird. Dafür gibt es eine Reihe technischer und methodischer Gründe, aber im Grunde ist es am besten, das globale Objekt nicht direkt zu verwenden (das war schon immer so, in ES6 sogar noch mehr).

Gibt es etwas Bestimmtes, für das Sie das globale Objekt benötigen?

+0

Hey Andreas, danke für dein Fachwissen! Ich habe Ihre Frage darüber beantwortet, warum ich das globale Objekt in ** Update 2 ** meines ursprünglichen Posts haben möchte. Könnten Sie einen Blick darauf werfen, ob das Muster, dem ich folge, ein gutes ist? Vielen Dank! –

0

Meistens ja.

Passing this in jedem Nicht-Objekt (oder nicht gesetzt this) auf das globale Objekt beziehen:

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

Dieses Verhalten soll in ES6 (für verständliche Abwärtskompatibilitätsprobleme) bleiben. Und so greifen die meisten plattformübergreifenden (Browser/Node) Plugins auf das globale Objekt zu. Zum Beispiel: https://github.com/documentcloud/underscore/blob/master/underscore.js#L12

Obwohl es stimmt, dass Plugin auf dem Server nur this als module zugreifen (die exportiert wird). Aber das wollen Sie im Knoten. Ihr globaler Speicherplatz wird noch nie bereinigt (außer wenn dies manuell oder beim Neustart des Servers erfolgt). So wird es zwischen allen Client-Verbindungen geteilt; Alles dem globalen Raum zuzuordnen, ist wirklich keine gute Idee.


Der einzige bemerkenswerte Unterschied, wie this ist in strict mode, wo es ein Fehler ist, wenn null oder undefined wird werfen, um call oder apply oder bind zwischen javascript „Version“ behandelt (in der Position der übergeben wird this value). Im unstrikten Modus wurde this nur auf das globale Objekt gezwungen.

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

Hoffe diese Hilfe!

+2

Sie konnten gerade in Ihrer Phrasierung unklar gewesen sein, aber 'foo.apply (null);' wirft keinen Fehler im strengen Modus. 'function foo() {this.doSomething(); } 'gibt einen Fehler im strikten Modus aus, wenn es kein 'this' gibt (zB wenn' this '' null' oder 'undefined' ist).Das mag sein, was du sagen wolltest, aber du möchtest es vielleicht deutlicher für die Nachwelt schreiben. –