Меню
Бесплатно
Главная  /  Интернет  /  Для чего используется строгий режим в js. Что делает "use strict" в JavaScript, и каковы причины этого? && — логическое И

Для чего используется строгий режим в js. Что делает "use strict" в JavaScript, и каковы причины этого? && — логическое И

Эта директива пишется в начале сценария или функции. Так и пишется:

И для чего же она нужна? Все что ниже директивы "use strict" , является строгим кодом. Строгий, это код, написанный по новому стандарту. Например, в старом стандарте можно было не объявлять переменную, а в новом нужно объявлять.

"use strict";
a = 10; // Ошибка: переменная не объявлена
document.write(a);

А так будет работать, если объявить переменную:

Var a;
"use strict";
a = 10;
document.write(a);

Эти пункты взяты из книги: "Дэвид Флэнаган - JavaScript. Подробное руководство (6-е издание)"

  • В строгом режиме не допускается использование инструкции with .
  • В строгом режиме все переменные должны объявляться: если попытаться присвоить значение идентификатору, который не является объявленной переменной, функцией, параметром функции, параметром конструкции catch или свойством глобального объекта, возбуждается исключение ReferenceError . (В нестрогом режиме такая попытка просто создаст новую глобальную переменную и добавит ее в виде свойства в глобальный объект.)
  • В строгом режиме функции, которые вызываются как функции (а не как методы), получают в ссылке this значение undefined . (В нестрогом режиме функции, которые вызываются как функции, всегда получают в ссылке this глобальный объект.) Это отличие можно использовать, чтобы определить, поддерживает ли та или иная реализация строгий режим: var hasStrictMode = (function() { "use strict"; return this===undefined}()); Кроме того, когда функция вызывается в строгом режиме с помощью call() или apply() , значение ссылки this в точности соответствует значению, переданному в первом аргументе функции call() или apply() . (В нестрогом режиме значения null и undefined замещаются ссылкой на глобальный объект, а простые значения преобразуются в объекты.)
  • В строгом режиме попытки присвоить значения свойствам, недоступным для записи, или создать новые свойства в нерасширяемых объектах порождают исключение TypeError . (В нестрогом режиме эти попытки просто игнорируются.)
  • В строгом режиме программный код, передаваемый функции eval() , не может объявлять переменные или функции в области видимости вызывающего программного кода, как это возможно в нестрогом режиме. Вместо этого переменные и функции помещаются в новую область видимости, создаваемую для функции eval() . Эта область видимости исчезает, как только eval() вернет управление.
  • В строгом режиме объект arguments в функции хранит статическую копию значений, переданных функции. В нестрогом режиме объект arguments ведет себя иначе – элементы массива arguments и именованные параметры функции ссылаются на одни и те же значения.
  • В строгом режиме возбуждается исключение SyntaxError , если оператору delete передать неквалифицированный идентификатор, такой как имя переменной, функции или параметра функции. (В нестрогом режиме такое выражение delete не выполнит никаких действий и вернет false .)
  • В строгом режиме попытка удалить ненастраиваемое свойство приведет к исключению TypeError . (В нестрогом режиме эта попытка просто завершится неудачей и выражение delete вернет false .)
  • В строгом режиме попытка определить в литерале объекта два или более свойств с одинаковыми именами считается синтаксической ошибкой. (В нестрогом режиме ошибка не возникает.)
  • В строгом режиме определение двух или более параметров с одинаковыми именами в объявлении функции считается синтаксической ошибкой. (В нестрогом режиме ошибка не возникает.)
  • В строгом режиме не допускается использовать литералы восьмеричных целых чисел (начинающихся с 0, за которым не следует символ x). (В нестрогом режиме некоторые реализации позволяют использовать восьмеричные литералы.)
  • В строгом режиме идентификаторы eval и arguments интерпретируются как ключевые слова, и вы не можете изменить их значения. Вы сможете присвоить значения этим идентификаторам, объявив их как переменные, использовав их в качестве имен функций, имен параметров функций или идентификаторов блока catch .
  • В строгом режиме ограничивается возможность просмотра стека вызовов. Попытки обратиться к свойствам arguments.caller arguments.callee и в строгом режиме возбуждают исключение TypeError . Попытки прочитать свойства caller и arguments функций в строгом режиме также возбуждают исключение TypeError . (Некоторые реализации определяют эти свойства в нестрогих функциях.)

В этой статье мы рассмотрим одну из важнейших функциональностей JavaScript , называемую "строгим режимом" (strict mode ).

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

Использование "strict mode "

Чтобы начать выполнять код в строгом режиме, нам нужно использовать директиву «use strict». Это просто выражение. Эта директива поддерживается в JavaScript 1.8.5 (ECMAScript 5 ) или выше.

Использование директивы «use strict»

Существует два способа использования директивы «use strict» . Мы можем использовать ее или внутри объявления функции в самом начале или в глобальном объявлении – в начале файла.
Когда мы используем режим «strict mode » как глобальную директиву, весь код javascript на странице выполняется в строгом режиме. Например:

Function print(value) {
console.log (value);
}

Когда мы используем «use strict» внутри объявления функции, весь код внутри функции выполняется в строгом режиме. Весь другой код вне функции выполняется в обычном режиме.
Например:

Function print(value) {
"use strict"
console.log (value);
}

Function print_twice(value) {
console.log (value);
console.log (value);
}

Что мы не можем сделать в строгом режиме: Использование необъявленной переменной

В строгом режиме мы не можем использовать необъявленную переменную.

"use string"
a = 12; // выбрасывается исключение в строгом режиме. В нестрогом режиме создается новое свойство для объекта window.

Оператор delete

Оператор delete используется для удаления пользовательских свойств у объекта и элементов массива. Если мы попытаемся удалить что-либо, кроме определенных пользователем свойств объекта или элементов массива, мы получим исключение.

Var a = 78;
window.b = 34;

Function print () {}
window.c = function () {}

Delete a; // генерирует исключение в строгом режиме. В стандартном режиме он возвращает false и программа продолжает работу

Delete window.a; // генерирует исключение в строгом режиме. В нестандартном режиме он возвращает false и программа продолжается.

Delete window.b; // В обоих режимах свойство b удаляется
.
delete Math.PI; // В нестрогом режиме он возвращает false, поскольку PI предварительно определен. В строгом режиме - исключение.

Delete Object.prototype; // удаление встроенного свойства в нестрогом режиме возвращает false. Но в строгом режиме выбрасывается исключение.

Просто помните, что везде, где delete возвращает false в нестрогом режиме, он выдает исключение в строгом режиме.

Многократное объявление свойств

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

Var myObject = {property1: 1, property2: 2, property1: 1}; // генерирует исключение.

На этом все, а в следующей статье мы продолжим изучать директиву JavaScript "use strict".

Sometimes you"ll see the default, non-strict mode referred to as " " . This isn"t an official term, but be aware of it, just in case.

JavaScript"s strict mode, introduced in ECMAScript 5, is a way to opt in to a restricted variant of JavaScript, thereby implicitly opting-out of " ". Strict mode isn"t just a subset: it intentionally has different semantics from normal code. Browsers not supporting strict mode will run strict mode code with different behavior from browsers that do, so don"t rely on strict mode without feature-testing for support for the relevant aspects of strict mode. Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally.

Strict mode makes several changes to normal JavaScript semantics:

  • Eliminates some JavaScript silent errors by changing them to throw errors.
  • Fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that"s not strict mode.
  • Prohibits some syntax likely to be defined in future versions of ECMAScript.
  • (function() { "use strict"; false.true = ""; // TypeError (14).sailing = "home"; // TypeError "with".you = "far away"; // TypeError })(); Simplifying variable uses

    Strict mode simplifies how variable names map to particular variable definitions in the code. Many compiler optimizations rely on the ability to say that variable X is stored in that location: this is critical to fully optimizing JavaScript code. JavaScript sometimes makes this basic mapping of name to variable definition in the code impossible to perform until runtime. Strict mode removes most cases where this happens, so the compiler can better optimize strict mode code.

    First, strict mode prohibits with . The problem with with is that any name inside the block might map either to a property of the object passed to it, or to a variable in surrounding (or even global) scope, at runtime: it"s impossible to know which beforehand. Strict mode makes with a syntax error, so there"s no chance for a name in a with to refer to an unknown location at runtime:

    "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; }

    The simple alternative of assigning the object to a short name variable, then accessing the corresponding property on that variable, stands ready to replace with .

    Second, . In normal code eval("var x;") introduces a variable x into the surrounding function or the global scope. This means that, in general, in a function containing a call to eval every name not referring to an argument or local variable must be mapped to a particular definition at runtime (because that eval might have introduced a new variable that would hide the outer variable). In strict mode eval creates variables only for the code being evaluated, so eval can"t affect whether a name refers to an outer variable or some local variable:

    Var x = 17; var evalX = eval(""use strict"; var x = 42; x;"); console.assert(x === 17); console.assert(evalX === 42);

    If the function eval is invoked by an expression of the form eval(...) in strict mode code, the code will be evaluated as strict mode code. The code may explicitly invoke strict mode, but it"s unnecessary to do so.

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

    Thus names in strict mode eval code behave identically to names in strict mode code not being evaluated as the result of eval .

    Third, strict mode forbids deleting plain names. delete name in strict mode is a syntax error:

    "use strict"; var x; delete x; // !!! syntax error eval("var y; delete y;"); // !!! syntax error

    Making eval and arguments simpler

    Strict mode makes arguments and eval less bizarrely magical. Both involve a considerable amount of magical behavior in normal code: eval to add or remove bindings and to change binding values, and arguments by its indexed properties aliasing named arguments. Strict mode makes great strides toward treating eval and arguments as keywords, although full fixes will not come until a future edition of ECMAScript.

    First, the names eval and arguments can"t be bound or assigned in language syntax. All these attempts to do so are syntax errors:

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

    Second, strict mode code doesn"t alias properties of arguments objects created within it. In normal code within a function whose first argument is arg , setting arg also sets arguments , and vice versa (unless no arguments were provided or arguments is deleted). arguments objects for strict mode functions store the original arguments when the function was invoked. arguments[i] does not track the value of the corresponding named argument, nor does a named argument track the value in the corresponding arguments[i] .

    Function f(a) { "use strict"; a = 42; return ; } var pair = f(17); console.assert(pair === 42); console.assert(pair === 17);

    Third, arguments.callee is no longer supported. In normal code arguments.callee refers to the enclosing function. This use case is weak: simply name the enclosing function! Moreover, arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed. arguments.callee for strict mode functions is a non-deletable property which throws an error when set or retrieved:

    "use strict"; var f = function() { return arguments.callee; }; f(); // throws a TypeError

    "Securing" JavaScript

    Strict mode makes it easier to write "secure" JavaScript. Some websites now provide ways for users to write JavaScript which will be run by the website on behalf of other users . JavaScript in browsers can access the user"s private information, so such JavaScript must be partially transformed before it is run, to censor access to forbidden functionality. JavaScript"s flexibility makes it effectively impossible to do this without many runtime checks. Certain language functions are so pervasive that performing runtime checks has a considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks.

    First, the value passed as this to a function in strict mode is not forced into being an object (a.k.a. "boxed"). For a normal function, this is always an object: either the provided object if called with an object-valued this ; the value, boxed, if called with a Boolean, string, or number this ; or the global object if called with an undefined or null this . (Use call , apply , or bind to specify a particular this .) Not only is automatic boxing a performance cost, but exposing the global object in browsers is a security hazard because the global object provides access to functionality that "secure" JavaScript environments must restrict. Thus for a strict mode function, the specified this is not boxed into an object, and if unspecified, this will be 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);

    That means, among other things, that in browsers it"s no longer possible to reference the window object through this inside a strict mode function.

    Second, in strict mode it"s no longer possible to "walk" the JavaScript stack via commonly-implemented extensions to ECMAScript. In normal code with these extensions, when a function fun is in the middle of being called, fun.caller is the function that most recently called fun , and fun.arguments is the arguments for that invocation of fun . Both extensions are problematic for "secure" JavaScript because they allow "secured" code to access "privileged" functions and their (potentially unsecured) arguments. If fun is in strict mode, both fun.caller and fun.arguments are non-deletable properties which throw when set or retrieved:

    Function restricted() { "use strict"; restricted.caller; // throws a TypeError restricted.arguments; // throws a TypeError } function privilegedInvoker() { return restricted(); } privilegedInvoker();

    Third, arguments for strict mode functions no longer provide access to the corresponding function call"s variables. In some old ECMAScript implementations arguments.caller was an object whose properties aliased variables in that function. This is a security hazard because it breaks the ability to hide privileged values via function abstraction; it also precludes most optimizations. For these reasons no recent browsers implement it. Yet because of its historical functionality, arguments.caller for a strict mode function is also a non-deletable property which throws when set or retrieved:

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

    Paving the way for future ECMAScript versions

    Future ECMAScript versions will likely introduce new syntax, and strict mode in ECMAScript 5 applies some restrictions to ease the transition. It will be easier to make some changes if the foundations of those changes are prohibited in strict mode.

    First, in strict mode, a short list of identifiers become reserved keywords. These words are implements , interface , let , package , private , protected , public , static , and yield . In strict mode, then, you can"t name or use variables or arguments with these names.

    Function package(protected) { // !!! "use strict"; var implements; // !!! interface: // !!! while (true) { break interface; // !!! } function private() { } // !!! } function fun(static) { "use strict"; } // !!!

    Two Mozilla-specific caveats: First, if your code is JavaScript 1.7 or greater (for example in chrome code or when using the right ) and is strict mode code, let and yield have the functionality they"ve had since those keywords were first introduced. But strict mode code on the web, loaded with or ... , won"t be able to use let / yield as identifiers. Second, while ES5 unconditionally reserves the words class , enum , export , extends , import , and super , before Firefox 5 Mozilla reserved them only in strict mode.

    Second, . In normal mode in browsers, function statements are permitted "everywhere". This is not part of ES5 (or even ES3)! It"s an extension with incompatible semantics in different browsers. Note that function statements outside top level are permitted in 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 }

    This prohibition isn"t strict mode proper because such function statements are an extension of basic ES5. But it is the recommendation of the ECMAScript committee, and browsers will implement it.

    Strict mode in browsers

    The major browsers now implement strict mode. However, don"t blindly depend on it since there still are numerous Browser versions used in the wild that only have partial support for strict mode or do not support it at all (e.g. Internet Explorer below version 10!). Strict mode changes semantics. Relying on those changes will cause mistakes and errors in browsers which don"t implement strict mode. Exercise caution in using strict mode, and back up reliance on strict mode with feature tests that check whether relevant parts of strict mode are implemented. Finally, make sure to test your code in browsers that do and don"t support strict mode . If you test only in browsers that don"t support strict mode, you"re very likely to have problems in browsers that do, and vice versa.

    Specifications Specification Status Comment
    ECMAScript 5.1 (ECMA-262)
    Standard Initial definition. See also:
    ECMAScript 2015 (6th Edition, ECMA-262)
    The definition of "Strict Mode Code" in that specification.
    Standard Strict mode restriction and exceptions
    ECMAScript Latest Draft (ECMA-262)
    The definition of "Strict Mode Code" in that specification.
    Draft

    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!). Строгий режим изменяет семантику. Опора на эти изменения приведет к ошибкам и ошибкам в браузерах, которые не реализуют строгий режим. Соблюдайте осторожность при использовании строгого режима и поддерживайте уверенность в строгом режиме с функциональными тестами, которые проверяют, применяются ли соответствующие части строгого режима. Наконец, обязательно проверьте свой код в браузерах, которые выполняют и не поддерживают строгий режим . Если вы тестируете только в браузерах, которые не поддерживают строгий режим, вы, скорее всего, будете иметь проблемы с браузерами, которые это делают, и наоборот.

    7 ответов

    Его основная цель - сделать больше проверок.

    Просто добавьте "use strict"; вверху вашего кода, прежде чем что-либо еще.

    Например, blah = 33; действителен JavaScript. Это означает, что вы создаете полностью глобальную переменную blah .

    Но в строгом режиме это ошибка, потому что вы не использовали ключевое слово "var" для объявления переменной.

    В большинстве случаев вы не хотите создавать глобальные переменные в середине некоторой произвольной области, поэтому большую часть времени, когда blah = 33 записывается, это ошибка, и программист фактически не хотел, чтобы это было глобальная переменная, они хотели написать var blah = 33 .

    Аналогичным образом запрещается много вещей, которые являются технически обоснованными. NaN = "lol" не вызывает ошибку. Он также не изменяет значение NaN. используя строгие эти (и подобные странные утверждения), вызывают ошибки. Большинство людей это ценят, потому что нет оснований когда-либо писать NaN = "lol" , поэтому, скорее всего, была опечатка.

    Один из аспектов строгого режима, о котором уже не упоминалось в ответе Саймона, заключается в том, что строгий режим устанавливает this в undefined в функции, вызываемые посредством вызова функции.

    Итак, подобные вещи

    Function Obj() { this.a = 12; this.b = "a"; this.privilegedMethod = function () { this.a++; privateMethod(); }; function privateMethod() { this.b = "foo"; } }

    приведет к ошибке при вызове privateMethod (поскольку вы не можете добавить свойство в undefined), вместо того, чтобы бесполезно добавлять свойство b к глобальному объекту.

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

    В ECMAScript 5 введена концепция строгой моды.

    Вызов строгого режима в коде

    Строгий режим применяется ко всем скриптам или к отдельной функции. Он не применяется к инструкции блока, заключенной в {} фигурные скобки, попытка применить ее к таким контекстам ничего не делает.

    Целый Script:

    Скажем, мы создаем app.js, поэтому добавление использования первого выражения script приведет к строгому режиму для всего кода.

    // app.js whole script in strict mode syntax "use strict"; // Now you can start writing your code

    Строгий режим для функции:

    Чтобы вызвать строгий режим для функции, поставьте точное утверждение "use strict"; в начале тела функции перед любым другим утверждением.

    Function yourFunc(){ "use strict"; // Your function code logic }

    Строгий режим включает несколько изменений в обычную семантику Javascript. Первый строгий режим устраняет некоторую ошибку JavaScript без изменений, изменяя их, чтобы выбросить ошибки.

    Для экземпляра: код с использованием строгого режима

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

    Теперь попробуйте обратиться к переменной x, не объявив ее без строгого режима.

    (function(){ x = 3; })(); // Will not throw an error

    Преимущество использования строгого режима:

    • Устранить ошибки JavaScript без ошибок.
    • Исправлена ​​ошибка, которая затрудняет выполнение JavaScript-движка.
    • Сделать код быстрее, чем тот же код, который не работает в строгом режиме
    • Запрещает некоторый синтаксис, который может быть определен в будущей версии ECMAScript.