Posso disattivare ECMAscript modalità rigorosa per funzioni specifiche?
-
14-11-2019 - |
Domanda
Non ho trovato nulla riguardo la mia domanda qui su MDC o ECMAscript specifiche.Probabilmente qualcuno ne sa una più 'sporca' modo per risolvere questo.
Sto chiamando "use strict"
su ogni file javascript nel mio ambiente.Tutti i miei file di avvio come questo
(function(win, doc, undef) {
"use strict";
// code & functions
}(window, window.document));
Ora, io ho una funzione personalizzata che gestisce gli errori.Che funzioni utilizza il .caller
proprietà per fornire un contesto traccia dello stack.Assomiglia a questo:
var chain = (function() {
var _parent = _error,
_ret = '';
while( _parent.caller ) {
_ret += ' -> ' + _parent.caller.name;
_parent = _parent.caller;
}
return _ret;
}());
Ma, ovviamente, in modalità rigorosa .caller
non è eliminabile elica che genera quando viene recuperato.Quindi la mia domanda è, c'è qualcuno a conoscenza di un modo per disattivare stretto di più la funzione "saggio" ?
"use strict";
è ereditato da tutte le funzioni dopo che è stato chiamato.Ora abbiamo la possibilità di utilizzare solo la modalità rigorosa in specifiche funzioni di chiamata "use strict";
in cima a queste, ma c'è un modo per raggiungere il contrario ?
Soluzione
No, non è possibile disabilitare la modalità rigorosa per funzione.
È importante capire che la modalità rigorosa opere dal punto di vista lessicale;significato — che colpisce dichiarazione di funzione, non di esecuzione.Qualsiasi funzione dichiarato all'interno di un severo codice diventa una rigorosa funzione stessa.Ma non una qualsiasi funzione chiamato dall'interno di un severo codice è necessariamente rigorosa:
(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
}
Si noti come possiamo definire la funzione al di fuori di un severo codice e poi passarlo alla funzione che rigorosa.
Si può fare qualcosa di simile nel tuo esempio — hanno un oggetto con "sciatta" funzioni, quindi passare l'oggetto di una stretta immediatamente richiamato funzione.Naturalmente, che non funziona se "sciatta" le funzioni è necessario fare riferimento a variabili dall'interno principale funzione wrapper.
Anche notare che indiretta eval — suggerito da qualcun altro — non davvero aiutare qui.Non fa altro che eseguire il codice nel contesto globale.Se si tenta di chiamare una funzione definita a livello locale, indiretti eval non anche trovare:
(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')();
})();
Questa confusione globale eval probabilmente deriva dal fatto che globale eval può essere utilizzato per ottenere l'accesso a global oggetto da strict mode (che non è semplicemente accessibile tramite this
più):
(function(){
"use strict";
this; // undefined
(1,eval)('this'); // global object
})();
Ma tornando alla domanda...
È possibile tipo di trucco e di dichiarare una nuova funzione tramite Function
costruttore — che succede non ereditano rigore, ma che affidano (non standard) funzione di decompilazione e si sarebbe perdere la capacità di fare riferimento a variabili esterne.
(function(){
"use strict";
function strict(){ /* ... */ }
// compile new function from the string representation of another one
var sneaky = Function('return (' + strict + ')()');
sneaky();
})();
Nota che FF4+ sembra in disaccordo con spec (da quello che posso dire) e in modo non corretto marchi funzione creata tramite Function
come rigoroso.Questo non accade in altri severi-modalità-supportare implementazioni (come Cromo 12+, IE10, WebKit).
Altri suggerimenti
(da http://javascriptweblog.words.com/2011/ 05/03 / JavaScript-Strict-mode / )
.(...) La modalità rigorosa non è applicata funzioni non rigorose che vengono invocate Dentro il corpo di una funzione rigorosa (o perché sono stati passati come argomenti o invocati utilizzando
call
oapply
).Quindi se si imposta i metodi di errore in un file diverso, senza modalità rigorosa, quindi passarli come parametro, in questo modo:
.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)
... dovrebbe funzionare.
Un'alternativa è semplicemente facendo questo
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);
.