2016-04-15 5 views
3

Angenommen, ich möchte etwas JavaScript-Code ausführen, wie kann ich den globalen Kontext so ändern, dass sogar unbegrenzte Funktionen, die darin definiert sind, an diesen neuen Kontext gebunden werden? Meine aktuelle Idee ist folgende:Ist es möglich, unbegrenzte Funktionen automatisch an etwas anderes als "Fenster" zu binden?

(function() { 
    var window = {foo: 'bar'}; // just an example 

    (function() { 
    // PUT CODE HERE 
    }).call(window); 
})(); 

Dies funktioniert für einfache Dinge. Sowohl der Rahmen der inneren Funktion und das window Objekt wird auf die Variable verweisen ich erklärte:

(function() { 
    var window = {foo: 'bar'}; // just an example 

    (function() { 
    // <CODE> 
    console.log(this, window); 
    // </CODE> 
    }).call(window); 
})(); 

Der Ausgang ist das, was ich erwartet hatte: Object {foo: "bar"} Object {foo: "bar"}.

Aber wenn der innere Code ohne Angabe ihrer Funktion definiert this Objekt (beispielsweise nicht Function.prototype.bind nicht verwendet), erhält sie automatisch die ursprünglichen window Objekt als this. Überprüfen Sie den folgenden Code und seine Ausgabe:

(function() { 
    var window = {foo: 'bar'}; 

    (function() { 
    // <CODE> 
    console.log(this, window); 
    (function() { 
     console.log(this, window); 
    })(); 
    // </CODE> 
    }).call(window); 
})(); 

// This code outputs: 
Object {foo: "bar"} Object {foo: "bar"} 
Window {external: Object, chrome: Object, document: document, configData: Object, speechSynthesis: SpeechSynthesis…} Object {foo: "bar"} 

Gibt es eine Möglichkeit, wirklich ein Stück Code zu bekommen Zugriff auf die ursprüngliche window Objekt isolieren?

+1

Man könnte immer mit 'var global = Function auf das Fenster zugreifen ('return this')();' –

+0

@YuryTarabanko Das sollte die Antwort sein (dh "nein"). Selbst wenn die äußere Funktion hier in einen strikten Modus versetzt wird (der das innerste "Dies" daran hindert, es zu bekommen), funktioniert das immer noch, um das "Fenster" in der innersten Funktion zu erhalten. –

Antwort

2

Wenn Sie den strikten Modus verwenden, wird die Funktion ohne einen definierten Kontext (new, bind, call, apply) aufgerufen. Dies ist nicht definiert und kann daher das globale Objektfenster nicht ändern. Ich empfehle Ihnen, mozilla documentation about strict mode zu lesen. Wo finden Sie die folgenden Sätze finden:

Das bedeutet unter anderem, dass es nicht mehr möglich, das Fenster Objekt durch diesen in einer strengen Modus Funktion verweisen in Browsern.

sich zu überzeugen, können Sie diesen Code in einem Browser versuchen:

function useStrictMode() { 
    'use strict'; 
    console.log(this); 
} 

function noStrict() { 
    console.log(this); 
} 

useStrictMode(); //log undefined 
noStrict(); //log window 

Putting zu einem Anfang einer Datei ‚use strict‘ wird der gesamte Inhalt der Datei es verwenden machen. Es kann jedoch ein Problem haben, wenn Sie Ihre js-Datei mit anderen Dateien verknüpfen. In der Tat kann 'use strict' das Verhalten eines Codes ändern und einige Bibliotheken beschädigen. Dies ist einer der Gründe, warum es immer den gesamten Code in einer anonymen Funktion empfohlen einzuwickeln: „Gibt es eine Möglichkeit, wirklich ein Stück Code von isolieren Zugriff auf das ursprüngliche Fenster-Objekt bekommen“

(function(){ 
    'use strict'; 

    //your code go here, function declaration here will use strict mode to 
})(); 
+0

Um genau zu sein, fügen Sie ''use strict';' als erste Zeile innerhalb der ersten Funktion hinzu. Dies ergibt die Ausgabe von: 'Objekt {foo:" bar "} Objekt {foo:" bar "}' ... 'undefined Objekt {foo:" bar "}' –

+0

Und hier ist das Beispiel: https: // jsfiddle .net/3rnyp6dn/ –

+1

@RaulFernandez idealerweise ''verwenden strict';' sollte innerhalb der Funktion sein, so dass es den globalen Geltungsbereich nicht beeinträchtigt. Wenn Sie den strikten Modus global verwenden, können Probleme mit dem Code von Drittanbietern auftreten. –

Verwandte Themen