Question

Je ne trouve rien sur ma question ici sur MDC ou les spécifications ECMAScript. Probablement quelqu'un connaît une manière plus «hacky» de résoudre ce problème.

j'appelle "use strict" sur chaque fichier javascript de mon environnement. Tous mes fichiers commencent comme ça

(function(win, doc, undef) {
    "use strict";

    // code & functions
}(window, window.document));

Maintenant, j'ai une fonction personnalisée qui gère les erreurs. Que les fonctions utilisent le .caller propriété pour fournir un Trace de pile de contexte. Ressemble à ça:

var chain = (function() {
    var _parent = _error,
        _ret = '';

    while( _parent.caller ) {
        _ret += ' -> ' + _parent.caller.name;
        _parent = _parent.caller;
    }

    return _ret;
}());

Mais bien sûr, en mode strict .caller est un accessoire non séquesible qui lance lorsqu'il est récupéré. Donc ma question est, est-ce que tout le monde est conscient du chemin désactiver strict plus "en fonction de la fonction"?

"use strict"; est hérité par toutes les fonctions une fois qu'elle a été appelée. Maintenant, nous avons la possibilité d'utiliser simplement le mode strict dans des fonctions spécifiques en appelant simplement "use strict"; Au sommet de ceux-ci, mais y a-t-il un moyen d'atteindre le contraire?

Était-ce utile?

La solution

Non, vous ne pouvez pas désactiver le mode strict par fonction.

Il est important de comprendre que le mode strict fonctionne en lexicalement; Signification - Il affecte la déclaration de fonction, pas l'exécution. Toute fonction déclaré Dans le code strict devient une fonction stricte elle-même. Mais pas aucune fonction appelé De l'intérieur du code strict est nécessairement strict:

(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
}

Remarquez comment nous pouvons définir la fonction en dehors du code strict Et puis passez-le dans la fonction stricte.

Vous pouvez faire quelque chose de similaire dans votre exemple - avoir un objet avec des fonctions "bâclées", puis transmettre cet objet à cette fonction stricte immédiatement invoquée. Bien sûr, cela ne fonctionnera pas si les fonctions "sloppy" doivent référencer les variables à partir de la fonction de wrapper principale.

Notez également que évaluation indirecte - suggéré par quelqu'un d'autre - n'aidera pas vraiment ici. Tout ce qu'il fait est d'exécuter du code dans un contexte global. Si vous essayez d'appeler une fonction définie localement, Indirect EVE ne le trouvera même pas:

(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')();

})();

Cette confusion à propos de Global Eval provient probablement du fait que Global Evor this plus):

(function(){
  "use strict";

  this; // undefined
  (1,eval)('this'); // global object
})();

Mais revenons à la question ...

Vous pouvez en quelque sorte tricher et déclarer une nouvelle fonction via Function constructeur - qui arrive à pas hériter rigueur, mais cela compterait sur la décompilation de la fonction (non standard) et vous le feriez perdre la capacité de référencer les variables extérieures.

(function(){
  "use strict";

  function strict(){ /* ... */ }

  // compile new function from the string representation of another one
  var sneaky = Function('return (' + strict + ')()');

  sneaky();
})();

Notez que FF4 + semble être en désaccord avec les spécifications (de ce que je peux dire) et marque à tort la fonction créée via Function comme strict. Cela ne se produit pas dans d'autres Implémentations de support en mode strict (comme Chrome 12+, IE10, WebKit).

Autres conseils

(De http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/)

(...) Le mode strict n'est pas appliqué sur des fonctions non strictes qui sont invoquées à l'intérieur du corps d'une fonction stricte (soit parce qu'elles ont été transmises comme arguments ou invoquées en utilisant call ou apply).

Donc, si vous configurez les méthodes d'erreur dans un fichier différent, sans mode strict, puis passez-les comme un paramètre, comme ceci:

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)

... ça devrait fonctionner.

Une alternative est simplement de faire cela

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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top