Чи можу я вимкнути жорсткий режим ECMAscript для певних функцій?


78

Я не знаходжу нічого про своє запитання тут щодо MDC чи специфікацій ECMAscript. Напевно, хтось знає більш "хакі" спосіб вирішити це.

Я закликаю "use strict"кожен файл JavaScript у своєму середовищі. Всі мої файли починаються так

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

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

Тепер у мене є спеціальна функція, яка обробляє помилки. Ці функції використовують .callerвластивість для забезпечення трасування стека контексту . Виглядає так:

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

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

    return _ret;
}());

Але, звичайно, в суворому режимі .callerє непіддаленим підписом, який кидає при отриманні. Отже, моє запитання полягає в тому, чи знає хтось про спосіб відключення суворо більш «функціонально»?

"use strict";успадковується усіма функціями після його виклику. Тепер у нас є можливість просто використовувати строгий режим у конкретних функціях, просто зателефонувавши "use strict";вгорі, але чи є спосіб досягти протилежного?


Ви можете зламати його за допомогою глобального евалу, щоб обійти суворий режим
Райнос,

1
На випадок, якщо іншим потрібно буде знати, про що йдеться: Що означає строге виконання
mplungjan

Я майже сподіваюся, що чогось подібного не існує. Ідея "використовувати строго" - це стратегія відмови від зворотної сумісності. Я не впевнений, що мені подобається ідея прямої зворотної сумісності, коли ми дозволяємо коду ввійти, а потім дозволяємо підрозділам коду знову відмовитись.
davin

Ви можете подивитися тут >> просто змінити .babelrc рішення
hisland

Відповіді:


88

Ні, ви не можете вимкнути суворий режим для кожної функції.

Важливо розуміти, що суворий режим працює лексично ; значення - це впливає на оголошення функції, а не на виконання. Будь-яка функція, оголошена в рамках строгого коду, сама стає суворою функцією. Але не будь-яка функція, що викликається зсередини суворого коду, є обов'язково суворою:

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

Зверніть увагу, як ми можемо визначити функцію поза строгим кодом, а потім передати її у строгу функцію.

Ви можете зробити щось подібне у своєму прикладі - мати об’єкт із «недбалими» функціями, а потім передати цей об’єкт цій строгій функції, яка негайно викликається. Звичайно, це не спрацює, якщо "недбалі" функції потребують посилання на змінні всередині основної функції обгортки.

Також зауважте, що непряме оцінювання - запропоноване кимось іншим - тут насправді не допоможе. Все, що він робить, - це виконувати код у глобальному контексті. Якщо ви спробуєте викликати функцію, яка визначена локально, непрямий eval навіть не знайде її:

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

})();

Ця плутанина щодо глобального eval, мабуть, походить від того факту, що глобальний eval може використовуватися для отримання доступу до глобального об'єкта з суворого режиму (який вже не просто доступний через this):

(function(){
  "use strict";

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

Але повернемося до питання ...

Ви можете якось обдурити та оголосити нову функцію за допомогою Functionконструктора - це трапляється, що не успадковує строгість, але це буде покладатися на (нестандартну) декомпіляцію функції, і ви втратите здатність посилатися на зовнішні змінні .

(function(){
  "use strict";

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

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

  sneaky();
})();

Зверніть увагу, що FF4 +, здається, не погоджується зі специфікацією (з того, що я можу сказати) і неправильно позначає функцію, створену через Functionсувору. Цього не відбувається в інших реалізаціях, що підтримують суворий режим (наприклад, Chrome 12+, IE10, WebKit).


Як передати аргумент підлій функції?
Шимон Тода,

Дякую, у мене виникла потворна проблема під час тестування жасмину з необхідністю модифікувати глобальну змінну, що використовується тестованим класом, і я не зміг цього зробити. Чудовий чит!
Хуангі Джордан

@kangax, Якщо я використовую суворий режим, але я хочу його динамічно вимкнути. тобто, я оголошую функцію суворою, але в деяких випадках я не хочу, щоб ця функція була суворою, і я хочу змінити функцію як несувору. Що я повинен робити.?
Jeyanth

3

Альтернатива - це просто зробити це

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

3

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

(...) Строгий режим не застосовується до несуворих функцій, які викликаються всередині тіла суворої функції (або тому, що вони були передані як аргументи, або викликані за допомогою callабо apply).

Отже, якщо ви встановите методи помилок у іншому файлі, без суворого режиму, а потім передасте їх як параметр, наприклад:

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)

... це має спрацювати.


здається, не працює для мене в FF4. Я повністю видалив суворі інструкції щодо файлу та його методу, де знаходиться метод обробки помилок. Я все одно отримуватиму суворі помилки.
jAndy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.