Статьи

JavaScript: почему ненависть к строгому режиму?


Кажется, есть люди, которые ненавидят
строгий режим ECMAScript 5
. Этот пост показывает, что эта ненависть неоправданна и предоставляет обходные пути для отсутствующих функций.

Самый забавный пример ненависти в строгом режиме — в кодовой базе RiverTrail , где NBody.js начинается следующим образом:

    /*
     * ...
     */

    "DO NOT use strict";
    var NBody = {
        // ...

Но если вы посмотрите, какой строгий режим убирает, вы обнаружите, что он только делает JavaScript более чистым языком.

Обходы для отсутствующих функций

Строгий режим устраняет некоторые более сомнительные особенности JavaScript. Вот список того, чего не хватает и как обойти это:

  • Нет больше с заявлением. Это утверждение вызывает проблемы с производительностью и безопасностью [2]. Обходной путь: вместо
        with (obj.foo) {
            bar = ...;
        }
    

    Вы можете использовать IIFE [3] и написать

        (function (o) {
            o.bar = ...;
        }(obj.foo));
    
  • Нет больше arguments.caller. Это свойство было удалено из соображений безопасности (небезопасный код не должен иметь доступа к вызывающей стороне). Для него нет замены, вам придется ввести дополнительный параметр.
  • Нет больше arguments.callee. Это свойство предлагает удобный способ доступа к текущей функции внутри самой функции, без ссылки на глобальную переменную или переменную в окружающей области видимости.
        var MyMath = {
            fac: function (n) {
                if (n <= 0) {
                    return 1;
                } else {
                    return n * arguments.callee(n-1);
                }
            }
        };
    

    Назвали выражение функции выглядит как объявление функции (выписка), но на самом деле это выражение. Это дает функции имя, которое доступно только внутри функции. Это позволяет переписать приведенный выше код следующим образом:

        var MyMath = {
            fac: function me(n) {
                if (n <= 0) {
                    return 1;
                } else {
                    return n * me(n-1);
                }
            }
        };
    
  • Нет больше глобального доступа через это. Это всегда было скорее ошибкой, чем функцией — вы можете получить доступ к глобальному объекту через это в не-методах функций. Это может привести к случайному созданию глобальных переменных (например, если вы вызываете конструктор без нового). Ниже приведен пример законного использования:
        (function () {
            // private data
            ...
            // public data
            this.myModule = { // avoid!
                ...
            };
        }());
    

    Строгий режим не допускает вышеизложенного — это не определено в функциях, не относящихся к методам. Вы можете использовать следующие обходные пути:

        (function (global) {
            // private data
            ...
            // public data
            global.myModule = {
                ...
            };
        }(this)); // top-level |this| points to global object
    

    Но вам может даже не понадобиться доступ к глобальному объекту внутри IIFE:

        this.myModule = function () {
            // private data
            ...
            // public data
            return {
                ...
            };
        }();
    
  • Нет больше восьмеричных чисел. Теперь 0100 действительно 100, а не 64. И 08 уже не ошибка. Я не могу представить, что кто-то пропускает восьмеричные.

Все другие изменения, выполняемые в строгом режиме, такие как предотвращение дублирования имен параметров, служат только для более строгой проверки на наличие ошибок.

Связанное чтение

  1. Строгий режим JavaScript: резюме
  2. JavaScript с утверждением и почему он устарел
  3. Область видимости переменной JavaScript и ее подводные камни

 

С http://www.2ality.com/2011/10/strict-mode-hatred.html