When, why and how to use the "use Strict" directive in Javascript?

Asked

Viewed 27,772 times

66

I had never seen before the use of this directive, but almost all the most mature jQuery plugins use it.

I would like to know when and how to use it and what its purpose is.

  • 2

    use strict forces Javascript to use stricter rules for your code. It works well if you know what you’re doing. It’s good practice whenever you don’t have to keep bad code.

  • Would it be something like HTML Strict x transitional? If you have a well done and written HTML you should use Strict, but if you need a little more flexibility in breaking certain rules you use transitional. I could give an example where a JS code would work without the use of this directive, but it wouldn’t work using the same?

  • 1

    For example, the use strict does not allow you to create global variables accidentally. For example, if you do a = 5 within a function before declaring a with var, without the use strict you will create a global variable a. With the use strict, this will cause a mistake, because a was not defined.

  • @Philippegioseffi: In fact, HTML Strict and transitional do (practically) the same thing from the point of view of the Browser. The difference that matters is between docless documents (rendered in quirks mode) vs documents with some doctype (rendered according to the HTML standard). That’s why the recommended doctype nowadays is a simple <!doctype html>, no version number.

  • I’m not really an HTML expert, @missingno. But from what I saw the "use Strict" also does not largely affect the use of JS without the directive, ends up being almost the same thing.

  • @Philippegioseffi: "use Strict" helps you find one mound bug. It would be foolish to start a nine project without it. To tell the truth, the only reason this directive is not activated by default in browsers is that some of the changes are not backwards compatible and would break some existing websites.

  • I’m using it now and really pointed out several errors in Avascripts that we brought from other projects. It was easier to do on hand the right way.

  • I think it’s best to use "use Strict" in development and remove from production code.

  • @Gabrielsantos Why remove in production? Old browsers simply ignore the directive.

Show 4 more comments

6 answers

78


As others have said, Strict mode is a more rigorous way of interpreting language, which prohibits certain practices that have always been allowed but are not recommended (such as the creation of implicit global variables, already mentioned in other responses). Since unconditionally prohibiting such a practice would break legacy codes, it was decided to create the directive "use strict"; to activate the strict mode.

There are two ways to use "use strict":

  • At the top of the file, the directive applies the strict mode for the entire file.

  • As the first line of code of a function, the directive applies the strict mode only within the function (including other functions eventually declared within the function).

The great benefit of using Strict mode is to reduce the chance of hard-to-find bugs in the code (such as a name conflict when creating an implicit global, or the existence of two equal keys in literal object).

I have prepared a free and adapted translation of Annex C to the language specification, summarising existing restrictions in Strict mode:

  • The identifiers implements, interface, let, package, private, protected, public, static, and yield are reserved words when used in Strict mode.

  • Numeric literals are never considered octal, even when they start with zero. The same goes for octals escaped in strings, such as '\012' (modern browsers no longer support, even outside the Strict mode)

  • Trying to assign a value to a variable that does not exist in the current scope no longer creates a property in the global object (i.e., no longer creates a global variable). Instead, it launches an exception of the Referenceerror type. In addition, it is not possible to assign properties that have the {[Writable]]:false}attribute, nor to a accessor without Setter defined ({[Set]]:Undefined}), nor for properties of objects whose internal property [[Extensible]] is false. In all these cases a Typeerror will be launched.

  • Cannot reset eval, or use it with ++ or --.

  • If you try to access arguments.caller or arguments.callee in a function, a typeerror will be launched.

  • Named function arguments do not share values dynamically with numerically indexed equivalent properties. For example, in function foo(bar) { arguments[0] = 10; }, bar keeps the value passed in the call and does not assume the value 10.

  • The same is true in the opposite case: in function foo(bar) { bar = 10; }, arguments[0] keeps the value passed in the call and does not assume the value 10.

  • If there is more than one property with the same name on a literal object, a syntaxerror is launched.

  • "Eval" and "Arguments" identifiers cannot be used as function parameter names that define getters or setters on literal objects (even if the external code is not in Strict mode, but the getter/Setter body is).

  • The eval in Strict mode cannot instantiate variables or functions in the scope of who calls eval. The code passed to eval will create a new scope, where these variables will be instantiated.

  • In Strict mode, there is no coercion of this to the object. In cases where this for null or undefined, it will not be converted to the global object. For example: in function f(){ console.log(this) }; f();, this is undefined in Strict mode, and not the global object (in browsers, window). Also, if a primitive value is passed as this, he will not be converted to wrapper equivalent.

  • The operator delete launches a Syntaxerror when used on non-deleteable items such as variables, functions and arguments. For example: delete variavel, delete funcao and function(foo) { delete foo; }.

  • The operator delete launches a Typeerror if the property to be deleted has the attribute { [[Configurable]]:false }.

  • If you try to declare a variable with the name "Eval" or "Arguments", a Syntaxerror will be launched.

  • The use of with launches a Syntaxerror.

  • In a clause catch cannot use "Eval" or "Arguments" as the exception name; this is a Syntaxerror.

  • "Eval" and "Arguments" identifiers cannot be used as function parameter names; this is a syntaxerror.

  • Functions cannot have multiple parameters with the same name; this is a Syntaxerror.

  • Implementations are prohibited from extending the meaning of the "Caller" and "Arguments" properties of function instances beyond the specification.

  • It is a Syntaxerror trying to use "Eval" or "Arguments" as a function name or parameter, as well as trying to force it through the constructor Function.

  • 2

    Very elucidative the explanation, worth much this one more for already citing additions of the new version.

  • 2

    Thanks, @Philippegioseffi. And I will try to improve more the answer, I find it a little confusing yet because I did in a hurry.

20

Javascript is a dynamic language and it was not planned for the dimensions it is used today. So it has some little problems. For example the variable declaration, if you use a variable without var before it will become a global variable, so you may be overwriting a value that may be being used by some other function somewhere else. This kind of thing causes mistakes that are very hard to find.

This type of behavior is "natural" language and would break a lot of existing libraries if it were taken out of the language now.

The "use Strict" serves to try to mitigate these problems, browsers that recognize this directive will issue errors when they find code that is valid javascript but that is potentially problematic, such as the case of using variables without declaring with var. Old browsers that don’t recognize simply ignore the directive.

And since "use Strict" can be used in code blocks, you can use it within your new functions without having to refactor all your old libraries.

Example of use:

y = 2;//funciona sem problemas porque esta fora do bloco
function foo() {
  "use strict";
  x = 1;//emite erro em navegadores suportados
}

Reference: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/

7

'use Strict' is used to expose exceptions to your javascript code, seeing errors in more detail

Example

    function isStrictMode(){
      return !this;
    } 
    //retorna falso, uma vez que "this" se refere ao objeto global e '!this' se torna falso

    function isStrictMode(){   
      "use strict";
       return !this;
   } 
  //retorna verdadeiro, pois no modo estrito, a palavra-chave "this" não se refere ao objeto global, ao contrário JS tradicionais. Então, aqui, "this" é nulo e '!this' se torna verdade.
  • 1

    Could exemplify?

  • The link is good, including includes link to tell which browsers support or not this directive. I will not be able to use it here because I am obliged to write code that runs on Ies 7 and 8 that do not support this directive.

  • 1

    Although it is an interesting answer, it covers very little of what the directive does.

  • @utluiz for what I have seen almost everyone exemplifies in the same way, talking about global and non-global variables through the use of the variable declaration with var.

  • @Philippe Exemplify is one thing. However, the answer does not say, for example, that the mode scrict directly affects the way the script is executed by engine. I’m not saying the answer is bad or wrong, just incomplete.

  • Yeah, some of the answers below talk about it, including the information that some codes might stop working. A post that I found very interesting was that older browsers ignore the directive without causing major problems. Maybe it would be nice to compile some answers next to the question and create a Wiki. What do you think?

Show 1 more comment

5

Javascript was originally designed to be easy to learn by inexperienced programmers. And so they made Javascript into a language where you’re allowed to do all sorts of stupid things - the compiler rarely complains. I think everyone has already realised that it is better for the compiler to warn us of the mistakes we make, rather than silently ignoring the mistakes. "Strict mode" changes Javascript semantics to a stricter mode, in which probable error situations are rejected by the compiler. Example:

var length = 1;
...
lenght = 2;  // "length" mal escrito - em JavaScript normal
             // uma nova variável global chamada "lenght" é
             // criada
'use strict';
var length = 1;
...
lenght = 2;  // "length" mal escrito - em "strict mode" uma
             // excepção é lançada

It is important to note that the "Strict mode" changes the semantics of the program. A program that worked correctly without "Strict mode" can crash with "Strict mode" active. Moreover the "Strict mode" is not supported by all browsers, and therefore it is necessary to be careful because code that works correctly with the "Strict mode" active, may not work in browsers that do not support the "Strict mode".

4

Caio Gondim wrote a very good article about Infinite Loop that says the following:

Strict mode is a new Ecmascript 5 Feature that allows Javascript code to run in a more rigorous mode. In this mode, the Javascript engine has its behavior modified, generating errors that were previously silenced and even prohibiting the use of certain parts of the language that are considered problematic, thus forcing us to write better quality code and helping to catch bugs earlier.

There in the article it also exemplifies how to use. I suggest taking a look.

http://loopinfinito.com.br/2013/07/16/javascript-strict-mode/

4

"use Strict" is a directive where you are told that the compiler will not allow you to make faults in your code that are not considered errors by the interpreter, but may cause you headaches. For example, Javascript allows you to use a variable without being declared, or reset the variable Arguments on the job:

The code below is considered valid without the use of the "use Strict directive":

function f() {
  var arguments = [];
}

x = 0;

However, if used "use Strict":

"use strict";

function f() {
  var arguments = []; // SyntaxError: Variable name may not be eval or arguments in strict mode
}

x = 0; // ReferenceError: x is not defined
  • It helped me to find the difference in the strict way and the non-standard way... Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.