Ich finde hier zu MDC oder den ECMAscript-Spezifikationen nichts zu meiner Frage. Wahrscheinlich kennt jemand einen "hackigeren" Weg, um dies zu lösen.
Ich rufe "use strict"
jede Javascript-Datei in meiner Umgebung auf. Alle meine Dateien beginnen so
(function(win, doc, undef) {
"use strict";
// code & functions
}(window, window.document));
Jetzt habe ich eine benutzerdefinierte Funktion, die Fehler behandelt. Diese Funktion verwendet die .caller
Eigenschaft, um eine Kontextstapelverfolgung bereitzustellen . Sieht aus wie das:
var chain = (function() {
var _parent = _error,
_ret = '';
while( _parent.caller ) {
_ret += ' -> ' + _parent.caller.name;
_parent = _parent.caller;
}
return _ret;
}());
Aber im strengen Modus .caller
befindet sich natürlich eine nicht löschbare Requisite, die beim Abrufen ausgelöst wird. Meine Frage ist also, ist jemandem bekannt, wie man strikte "funktionale" deaktivieren kann ?
"use strict";
wird von allen Funktionen nach dem Aufruf geerbt. Jetzt haben wir die Möglichkeit, nur den strengen Modus in bestimmten Funktionen zu verwenden, indem wir nur oben aufrufen. "use strict";
Aber gibt es eine Möglichkeit, das Gegenteil zu erreichen?
Antworten:
Nein, Sie können den strengen Modus pro Funktion nicht deaktivieren.
Es ist wichtig zu verstehen, dass der strikte Modus lexikalisch funktioniert . Bedeutung - Dies wirkt sich auf die Funktionsdeklaration und nicht auf die Ausführung aus. Jede im strengen Code deklarierte Funktion wird selbst zu einer strengen Funktion. Aber keine Funktion, die innerhalb eines strengen Codes aufgerufen wird , ist notwendigerweise streng:
(function(sloppy) { "use strict"; function strict() { // this function is strict, as it is _declared_ within strict code } strict(); sloppy(); })(sloppy); function sloppy(){ // this function is not strict as it is _declared outside_ of strict code }
Beachten Sie, wie wir Funktionen außerhalb von striktem Code definieren und dann an die strikte Funktion übergeben können.
In Ihrem Beispiel können Sie etwas Ähnliches tun - ein Objekt mit "schlampigen" Funktionen haben und dieses Objekt dann an diese strenge, sofort aufgerufene Funktion übergeben. Das funktioniert natürlich nicht, wenn "schlampige" Funktionen Variablen aus der Haupt-Wrapper-Funktion heraus referenzieren müssen.
Beachten Sie auch, dass die indirekte Bewertung - von jemand anderem vorgeschlagen - hier nicht wirklich hilft. Es wird lediglich Code im globalen Kontext ausgeführt. Wenn Sie versuchen, eine lokal definierte Funktion aufzurufen, wird sie bei der indirekten Auswertung nicht einmal gefunden:
(function(){ "use strict"; function whichDoesSomethingNaughty(){ /* ... */ } // ReferenceError as function is not globally accessible // and indirect eval obviously tries to "find" it in global scope (1,eval)('whichDoesSomethingNaughty')(); })();
Diese Verwirrung über die globale Bewertung beruht wahrscheinlich auf der Tatsache, dass die globale Bewertung verwendet werden kann, um im strengen Modus (auf den nicht mehr einfach zugegriffen werden
this
kann) Zugriff auf globale Objekte zu erhalten :(function(){ "use strict"; this; // undefined (1,eval)('this'); // global object })();
Aber zurück zur Frage ...
Sie können eine neue Funktion über den
Function
Konstruktor betrügen und deklarieren - was zwar keine Strenge erbt , aber auf einer (nicht standardmäßigen) Funktionsdekompilierung beruht und Sie die Fähigkeit verlieren, auf äußere Variablen zu verweisen .(function(){ "use strict"; function strict(){ /* ... */ } // compile new function from the string representation of another one var sneaky = Function('return (' + strict + ')()'); sneaky(); })();
Beachten Sie, dass FF4 + nicht mit der Spezifikation übereinstimmt (soweit ich das beurteilen kann) und die über erstellte Funktion fälschlicherweise
Function
als streng markiert . Dies ist in anderen Implementierungen, die den strengen Modus unterstützen (wie Chrome 12+, IE10, WebKit), nicht der Fall.quelle
Eine Alternative ist einfach dies zu tun
var stack; if (console && console.trace) { stack = console.trace(); } else { try { var fail = 1 / 0; } catch (e) { if (e.stack) { stack = e.stack; } else if (e.stacktrace) { stack = e.stacktrace; } } } // have fun implementing normalize. return normalize(stack);
quelle
(Von http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/ )
Wenn Sie also die Fehlermethoden in einer anderen Datei ohne strengen Modus einrichten und sie dann wie folgt als Parameter übergeben:
var test = function(fn) { 'use strict'; fn(); } var deleteNonConfigurable = function () { var obj = {}; Object.defineProperty(obj, "name", { configurable: false }); delete obj.name; //will throw TypeError in Strict Mode } test(deleteNonConfigurable); //no error (Strict Mode not enforced)
...es sollte funktionieren.
quelle