Vysor — удобный инструмент для тестирования
Download Vysor App For Chrome Hello everyone, how are you all doing? I hope you are all having a great week so far. I...
Strict mode (в переводе с анг. - строгий режим) – это модель синтаксического анализа и выполнения JavaScript-кода, в которой используется более строгая проверка кода на ошибки и генерируются ошибки при небезопасных действиях.
Включение строгого режимаЧтобы включить строгий режим для всего сценария, добавьте в начало сценария следующую команду:
"use strict";
Хоть она и выглядит как строка, на самом деле это директива, переводящая JavaScript в строгий режим.
Строгий режим можно включить и для отдельной функции, добавив эту директиву в начало тела функции:
Function foo() { "use strict"; }
Директиву "use strict" можно указывать только в самом начале сценария или в самом начале функции. Это не означает, что она должна находиться в самой первой строке, но должна быть указана до других инструкций. Если директиву "use strict" указать не в начале, а в другом месте, она не будет работать:
"use strict"; // Правильное расположение a = 5; alert(a); b = 1; alert(b); a = 5; alert(a); "use strict"; // Неправильное расположение. Директива не будет работать b = 1; alert(b);
Выполнение JavaScript в строгом режимеЭта директива пишется в начале сценария или функции. Так и пишется:
И для чего же она нужна? Все что ниже директивы "use strict" , является строгим кодом. Строгий, это код, написанный по новому стандарту. Например, в старом стандарте можно было не объявлять переменную, а в новом нужно объявлять.
"use strict";
a = 10; // Ошибка: переменная не объявлена
document.write(a);
А так будет работать, если объявить переменную:
Var a;
"use strict";
a = 10;
document.write(a);
Эти пункты взяты из книги: "Дэвид Флэнаган - JavaScript. Подробное руководство (6-е издание)"
JavaScript - Strict mode
Строгий режимИногда вы увидите нестандартный режим по умолчанию, называемый « sloppy mode » . Это не официальный термин, но помните об этом, на всякий случай.
(function() { "use strict"; false.true = ""; // TypeError (14).sailing = "home"; // TypeError "with".you = "far away"; // TypeError })();
Упрощение использования переменныхСтрогий режим упрощает сопоставление имен переменных с конкретными определениями переменных в коде. Многие оптимизаторы компилятора полагаются на способность говорить, что переменная X хранится в этом месте: это имеет решающее значение для полной оптимизации кода JavaScript. JavaScript иногда делает это базовое отображение имени в определение переменной в коде, которое невозможно выполнить до выполнения. Строгий режим удаляет большинство случаев, когда это происходит, поэтому компилятор может лучше оптимизировать строгий режимный код.
Во-первых, строгий режим запрещается. Проблема заключается в том, что любое имя внутри блока может отображать либо свойство переданного ему объекта, либо переменную в окружении (или даже глобальную) во время выполнения: это невозможно заранее узнать. Строгий режим выполняется with синтаксической ошибкой, поэтому нет возможности для имени в a, которое ссылается на неизвестное местоположение во время выполнения:
"use strict"; var x = 17; with (obj) { // !!! syntax error // If this weren"t strict mode, would this be var x, or // would it instead be obj.x? It"s impossible in general // to say without running the code, so the name can"t be // optimized. x; }
Простая альтернатива назначения объекта короткой переменной имени, затем доступ к соответствующему свойству для этой переменной, готова заменить with .
Во-вторых, . В обычном коде eval("var x;") вводится переменная x в окружающую функцию или глобальную область. Это означает, что, вообще говоря, в функции, содержащей вызов eval каждое имя, не относящееся к аргументу или локальной переменной, должно отображаться в конкретное определение во время выполнения (поскольку этот eval мог бы ввести новую переменную, которая скроет внешнюю переменную). В строгом режиме eval создает переменные только для оцениваемого кода, поэтому eval не может повлиять на то, ссылается ли имя на внешнюю переменную или на некоторую локальную переменную:
Var x = 17; var evalX = eval(""use strict"; var x = 42; x;"); console.assert(x === 17); console.assert(evalX === 42);
Если функция eval вызывается выражением формы eval(...) в коде строгого режима, код будет оцениваться как строгий код режима. Код может явно ссылаться на строгий режим, но это необязательно.
Function strict1(str) { "use strict"; return eval(str); // str will be treated as strict mode code } function strict2(f, str) { "use strict"; return f(str); // not eval(...): str is strict if and only // if it invokes strict mode } function nonstrict(str) { return eval(str); // str is strict if and only // if it invokes strict mode } strict1(""Strict mode code!""); strict1(""use strict"; "Strict mode code!""); strict2(eval, ""Non-strict code.""); strict2(eval, ""use strict"; "Strict mode code!""); nonstrict(""Non-strict code.""); nonstrict(""use strict"; "Strict mode code!"");
Таким образом, имена в строгом коде eval кода ведут себя одинаково с именами в строгом режиме, который не оценивается как результат eval .
В-третьих, строгий режим запрещает удаление простых имен. delete name в строгом режиме - это синтаксическая ошибка:
"use strict"; var x; delete x; // !!! syntax error eval("var y; delete y;"); // !!! syntax error
Упрощение eval и argumentsСтрогий режим делает arguments и eval менее причудливо волшебными. Оба включают значительное количество магического поведения в нормальном коде: eval для добавления или удаления привязок и изменения значений привязки, а также arguments помощью индексированных свойств aliasing с именами аргументов. Строгий режим делает большие шаги для обработки eval и arguments качестве ключевых слов, хотя полные исправления не будут появляться до будущего выпуска ECMAScript.
Во-первых, имена eval и arguments не могут быть связаны или назначены в синтаксисе языка. Все эти попытки - синтаксические ошибки:
"use strict"; eval = 17; arguments++; ++eval; var obj = { set p(arguments) { } }; var eval; try { } catch (arguments) { } function x(eval) { } function arguments() { } var y = function eval() { }; var f = new Function("arguments", ""use strict"; return 17;");
Во-вторых, строгий код режима не поддерживает свойства объектов arguments созданных в нем. В нормальном коде внутри функции, первым аргументом которой является arg , параметр arg также устанавливает arguments и наоборот (если аргументы не предоставлены или arguments удалены). объекты arguments для функций строгого режима хранят исходные аргументы при вызове функции. arguments[i] не отслеживает значение соответствующего именованного аргумента, равно как и именованный аргумент не отслеживает значение в соответствующих arguments[i] .
Function f(a) { "use strict"; a = 42; return ; } var pair = f(17); console.assert(pair === 42); console.assert(pair === 17);
В-третьих, arguments.callee больше не поддерживается. В обычных arguments.callee относится к закрывающей функции. Этот случай использования слабый: просто назовите функцию включения! Кроме того, arguments.callee существенно затрудняет оптимизацию, например, встроенные функции, поскольку необходимо предоставить ссылку на не-встроенную функцию, если access.callee обращается к ней. arguments.callee для функций строгого режима - это неиспользуемое свойство, которое генерируется при установке или извлечении:
"use strict"; var f = function() { return arguments.callee; }; f(); // throws a TypeError
«Защита» JavaScriptСтрогий режим упрощает запись «безопасного» JavaScript. Некоторые веб-сайты теперь предоставляют пользователям возможность писать JavaScript, который будет запущен веб-сайтом от имени других пользователей . JavaScript в браузерах может получить доступ к личной информации пользователя, поэтому такой JavaScript должен быть частично преобразован до его запуска, чтобы подвергнуть цензуре доступ к запрещенной функциональности. Гибкость JavaScript делает невозможным сделать это без многих проверок времени выполнения. Некоторые языковые функции настолько распространены, что выполнение проверок времени выполнения имеет значительную стоимость. Несколько строгих настроек режима, а также требование, чтобы пользовательский JavaScript был строгим кодом режима и что он был вызван определенным образом, существенно уменьшает необходимость в этих проверках времени выполнения.
Во-первых, значение, переданное как функция функции в строгом режиме, не принудительно превращается в объект (он же «в коробке»). Для нормальной функции this всегда объект: либо предоставленный объект, если он вызван с объектно-значным; значение, в штучной упаковке, если вызывается с булевым, строковым или числом this ; или глобальный объект, если он вызван с undefined или null this . (Используйте call , apply или bind чтобы указать конкретное this .) Не только автоматический бокс для производительности, но и отображение глобального объекта в браузерах является угрозой безопасности, поскольку глобальный объект обеспечивает доступ к функциям, которые «защищают» среды JavaScript должны ограничить. Таким образом, для функции строгого режима указанное this не помещается в объект в объект, а если не указано, this будет undefined:
"use strict"; function fun() { return this; } console.assert(fun() === undefined); console.assert(fun.call(2) === 2); console.assert(fun.apply(null) === null); console.assert(fun.call(undefined) === undefined); console.assert(fun.bind(true)() === true);
Это означает, среди прочего, что в браузерах уже невозможно ссылаться на объект window через this внутри функции строгого режима.
Во-вторых, в строгом режиме уже невозможно «ходить» по стеклу JavaScript через общепринятые расширения в ECMAScript. В нормальном коде с этими расширениями, когда функция fun находится в середине fun.caller , fun.caller - это функция, которая в последнее время называется fun , а fun.arguments - это arguments для этого вызова fun . Оба расширения являются проблематичными для «безопасного» JavaScript, поскольку они позволяют «защищенному» коду получить доступ к «привилегированным» функциям и их (потенциально необеспеченным) аргументам. Если fun находится в строгом режиме, как fun.caller и fun.arguments - не fun.caller fun.arguments свойства, которые бросаются при установке или извлечении:
Function restricted() { "use strict"; restricted.caller; // throws a TypeError restricted.arguments; // throws a TypeError } function privilegedInvoker() { return restricted(); } privilegedInvoker();
В-третьих, arguments для функций строгого режима больше не обеспечивают доступа к переменным вызова соответствующих функций. В некоторых старых реализациях ECMAScript arguments.caller был объектом, свойства которого изменяли переменные в этой функции. Это является угрозой безопасности, поскольку она нарушает способность скрывать привилегированные значения посредством абстракции функции; это также исключает большинство оптимизаций. По этим причинам последние браузеры не реализуют его. Однако из-за своей исторической функциональности arguments.caller для функции строгого режима также является неистинным свойством, которое генерируется при установке или извлечении:
"use strict"; function fun(a, b) { "use strict"; var v = 12; return arguments.caller; // throws a TypeError } fun(1, 2); // doesn"t expose v (or a or b)
Проложить путь для будущих версий ECMAScriptБудущие версии ECMAScript, скорее всего, введут новый синтаксис, а строгий режим в ECMAScript 5 применяет некоторые ограничения для облегчения перехода. Будет легче внести некоторые изменения, если основы этих изменений запрещены в строгом режиме.
Во-первых, в строгом режиме короткий список идентификаторов становится зарезервированными ключевыми словами. Эти слова являются implements , interface , let , package , private , protected , public , static и yield . В строгом режиме вы не можете назвать или использовать переменные или аргументы с этими именами.
Function package(protected) { // !!! "use strict"; var implements; // !!! interface: // !!! while (true) { break interface; // !!! } function private() { } // !!! } function fun(static) { "use strict"; } // !!!
Два предостережения, специфичные для Mozilla: во-первых, если ваш код равен 1,8 или более (например, в хром-коде или при использовании права ) и является строгим кодом режима, let и let функции, которые они имеют так как эти ключевые слова были впервые введены. Но строгий режимный код в Интернете, загруженный или ... , не сможет использовать let / yield качестве идентификаторов. Во-вторых, в то время как ES5 безоговорочно резервирует слова class , enum , export , extends , import и super , прежде чем Firefox 5 Mozilla зарезервирует их только в строгом режиме.
Во-вторых, . В нормальном режиме в браузерах операторы функций разрешены «везде». Это не часть ES5 (или даже ES3)! Это расширение с несовместимой семантикой в разных браузерах. Обратите внимание, что в ES2015 допустимы утверждения функций за пределами верхнего уровня.
"use strict"; if (true) { function f() { } // !!! syntax error f(); } for (var i = 0; i < 5; i++) { function f2() { } // !!! syntax error f2(); } function baz() { // kosher function eit() { } // also kosher }
Этот запрет не является строгого режима, потому что такие заявления функций являются расширением базового ES5. Но это рекомендация комитета ECMAScript, и браузеры его реализуют.
Строгий режим в браузерахОсновные браузеры теперь реализуют строгий режим. Тем не менее, не слепо зависеть от него, так как все еще существуют многочисленные версии браузера, используемые в дикой природе, которые имеют частичную поддержку строгого режима или вообще не поддерживают его (например, Internet Explorer ниже версии 10!). Строгий режим изменяет семантику. Опора на эти изменения приведет к ошибкам и ошибкам в браузерах, которые не реализуют строгий режим. Соблюдайте осторожность при использовании строгого режима и поддерживайте уверенность в строгом режиме с функциональными тестами, которые проверяют, применяются ли соответствующие части строгого режима. Наконец, обязательно проверьте свой код в браузерах, которые выполняют и не поддерживают строгий режим . Если вы тестируете только в браузерах, которые не поддерживают строгий режим, вы, скорее всего, будете иметь проблемы с браузерами, которые это делают, и наоборот.
(далее в статье Strict Mode). Strict Mode накладывает слой ограничений на JavaScript, он отгораживает вас от опасных частей языка (те части, которые есть исторически, но лучше чтобы их не было) и позволяет снизить вероятность ошибки.
Пока читал эту статью я написал 38 тестов, покрывающих все правила Strict Mode, объявленные в спецификации ES5. Вы можете посмотреть насколько ваш браузер поддерживает эти справила .
Код каждого теста представлен в конце статьи, чтобы помочь вам лучше понять спецификацию. Вы также можете выполнить тест вручную, скопируя код в консоль. Весь исходный код находится в моем репозитории .
Firefox 4 уже полностью поддерживает Strict Mode, а Chrome 11 практически полностью. Strict Mode уже не за горами - давайте изучим его подробнее!
Как включить Strict Mode? Если добавить "use strict" в начало вашего JavaScript кода, то Strict Mode будет применен для всего кода:От переводчика: тут в статье шел огромный кусок кода, закинул его на pastebin
Заключение Запрещение обращение к некоторым возможностям языка для улучшения кода - вопрос спорный, давайте отложим эти споры. В защиту Strict Mode я хочу сказать, что это отличный компромисс между тотальными переменами (которые сломают обратную совместимость) и ничего не деланием (которое приведет к захламлению языка и научит разработчиков плохому). ECMA-262 5th Edition: The Strict Mode of ECMAScriptОт переводчика. Strict Mode поддерживают практически половина всех браузеров, кроме своих прекрасных ограничений и иммунитету к распространенным ошибкам Strict Mode дает и другие преимущества (статья mraleph). Скоро неиспользование Strict Mode станет плохим тоном (аналогично requestAnimationFrame vs setTimeout). Сейчас самое время начать эксперименты!
(далее в статье Strict Mode). Strict Mode накладывает слой ограничений на JavaScript, он отгораживает вас от опасных частей языка (те части, которые есть исторически, но лучше чтобы их не было) и позволяет снизить вероятность ошибки.
Пока читал эту статью я написал 38 тестов, покрывающих все правила Strict Mode, объявленные в спецификации ES5. Вы можете посмотреть насколько ваш браузер поддерживает эти справила .
Код каждого теста представлен в конце статьи, чтобы помочь вам лучше понять спецификацию. Вы также можете выполнить тест вручную, скопируя код в консоль. Весь исходный код находится в моем репозитории .
Firefox 4 уже полностью поддерживает Strict Mode, а Chrome 11 практически полностью. Strict Mode уже не за горами - давайте изучим его подробнее!
Как включить Strict Mode? Если добавить "use strict" в начало вашего JavaScript кода, то Strict Mode будет применен для всего кода:От переводчика: тут в статье шел огромный кусок кода, закинул его на pastebin
Заключение Запрещение обращение к некоторым возможностям языка для улучшения кода - вопрос спорный, давайте отложим эти споры. В защиту Strict Mode я хочу сказать, что это отличный компромисс между тотальными переменами (которые сломают обратную совместимость) и ничего не деланием (которое приведет к захламлению языка и научит разработчиков плохому). ECMA-262 5th Edition: The Strict Mode of ECMAScriptОт переводчика. Strict Mode поддерживают практически половина всех браузеров, кроме своих прекрасных ограничений и иммунитету к распространенным ошибкам Strict Mode дает и другие преимущества (статья ). Скоро неиспользование Strict Mode станет плохим тоном (аналогично ). Сейчас самое время начать эксперименты!