on page 233 of the ECMAScript 5th Edition we can read details about "use strict" activation and what it means for our code.Somebody believes this ES5 feature can help developers to write less errors ... well, I think not everything is that good as it looks.This post is about all those points with concrete examples.

No OctalIntegerLiteral or OctalEscapeSequence

Base 8 has not many use cases on daily JS tasks. As example, to obtain the number 8 in base 8 we can write something like 010 where:

alert(010 === 8);

The problem is that 01 is not enough to force the engine to consider that number a base 8 and it will be interpreted as 1 indeed. Fair enough, I personally don't give a hack about base 8 so this does not hurt, it's just slightly simplified numbers parsing.Same story for OctalEscapeSequence, no "octal magic" anymore.

No Global Variables

If our closure has a reference not defined in the outer scope, there is no global variable but a ReferenceError.

Above example is a classic one ... or better, a classic for newcomers with PHP or Python background, as example, where local variables are implicit and global one should be explicit.While Python has a sort of implicit scope lookup with classes, PHP introduced closures only recently (well, 5.3 which should be right now the default minor version in every bloody server).Since after 1 day of JavaScript development you should have got it (use var for local scope variables) I do believe this is more a limit, rather than a feature.First of all, the current situation is quite naif since FireFox does not throw anything, it just stop working, while other browsers may nicely ignore this "feature".Moreover, the moment we want to define a global reference we need to have in our closure a safe reference to the global context or we are simply screwed.The second part of this point is that if the reference has been defined as writable:false, aka read only as undefined is, a TypeError should be thrown.

(function(){"use strict"; undefined = 123; // throw TypeError}());

Funny enough, if we have nested scope that relies in undefined but the outer one has something like:

Safer arguments and eval

... but wasn't eval evil? Anyway, in the forth point of use strict specifications we have errors whenever we try to reassign arguments or eval.Fine for eval, but a kinda common arguments trick won't be usable anymore.

// this will not work anymore(function (context){"use strict"; arguments = [].slice.call(arguments, 1); // some operation with arguments as Array outerCallback.call(context, arguments);}());

Goodbye arguments caller and callee

Once again, arguments.callee is gone. Moreover, arguments.callee.caller is done as well but in this case it's not about the caller property, the whole callee concept is gone.

They call it "graceful migration", I call it WTF. If arguments is still there and it's a bloody object similar to an Array, why this object should throw an error with an undefined property?OK, it's about migration, but actually what use strict introduced here is caller and callee as new reserved words, at least for properties of arguments or whatever function ... well done ...

arguments indexes

Whenever you have noticed or not, if you change a named argument value the arguments object will be affected at the same time. Here a basic example:

To be honest, whenever it helps or not, I wonder who the hell ever used the first dynamic shared arguments indexed property value case on any sort of logic code ... was it an ES3 gotcha? Well, in such case I agree, it does not make fucking sense so ... thanks, I am sure somebody in this world will have problems about this new entry.However, somebody that does not know JavaScript and programming principles as well may have problems ( nothing personal man, you just did it wrong 'till now ).Sarcasm a part, it's good to have this clarification on specs.

Bindings and arguments

For strict mode functions, if an arguments object is created the binding of the local identifier arguments to the arguments object is immutable and hence may not be the target of an assignment expression. (10.5).

Well, if you get anything different form what I have said already about redefining the arguments reference/object, please do not hesitate to wake me up in the middle of the night while I am on vacations since seriously I cannot figure out what's this point about.

Unique Object Property Name

With ES3 we could have done something like:

(function (){ var o = { one: 1, one: 2 }; alert(o.one); // 2 ???}());

Now, since properties order is not granted at all even in a classic for(var key in obj){} loop, this point is about being not ambiguous and do the right assignment once. As summary, with use strict above example will produce an error: property name "one" appears more than once in object literal.Once again, if you ever tried to assign same property more than once ... well, I can just say it's good they made this less ambiguous but I do believe this won't improve anybody code quality (being a mistake every Unit Test would have spot in any case).

arguments and eval as reserved identifiers

It's just like that, an argument cannot be called eval or arguments otherwise we gonna have a SyntaxError.

Apparently eval has been maden a bit safer but I can see its evil nature all over the place without problems. Kinda good that function defined through eval inside a strict function are automatically strict as well so I guess this point is about strict inheritance through evaluation.

Strict this

There are different behaviors completely changed and it's not all about undefined === this.Actually, it's not about this as undefined at all, it's about not changing the reference to something different.There is a classic trick to obtain the global object in the most secure possible way:

Untill now, the this reference has always been changed into the global object if the context was null or undefined.Moreover, the reference has been changed into a proper object reference with primitives values such boolean, number, and string.

I don't remember I have ever defined properties runtime when the callback was about primitives values.To me is like using objects as trash bin since nothing can be possibly reused after the function has been invoked.This is what is changed in ES5 and use strict, there is no magic anymore when call or apply are used.A primitive value will be primitive, an undefined one will be undefined and null will be null.Here the test case:

It must be said that all these changes make life easier for engines behind the language since call and apply are widely used and all those checks about the context type and its eventual convertion are gone.At the same time I would have reserved null as only exception to retrieve the global context since we have no more any safe way to do it and this is in my opinion bad.

More greedy delete

While before we could have tried to delete variables, and without success:

Since to be able to set properties as non configurable we need ES5 already, I think this was a mistake in the use strict rules because I would expect the same behavior for something introduced in ES5 as well as Object.defineProperty is.

Goodbye with statement

Whenever you like it or not, the with statement is gone.I seriously do not want to spend more than I have done already about it so ... forget it, be happy about the choice and shut up or Mr Crockford and all minifiers will come out the dark wardrobe and punch you in the face.

Reserved arguments and eval identifiers

Everything else about use strict is related to arguments and eval keywords.These cannot be used in function expressions, declarations, as variables, these cannot be reassigned, these must be used exclusively for what these are ... got it?

Summary

ES5 introduced use strict to let developers be familiar with things that will disappear soon in the next version of JavaScript.I am not happy about many choices, specially regarding the caller property which was a must have for debugging and introspective purpose but ... hey, engines are not clever enough to activate these things when necessary but these engines are able to swap runtime a totally different behavior between a non strict function and a strict one.In few words we still do not have full JavaScript potential here because of this transition that is apparently revolutionary behind the scene, surely not the best present ever for all developers that got JavaScript and used few tricks when necessary to improve their application logic and, why not, security.Well ... deal with "use strict" and put it there by default or shut up for all new version of JavaScript ... this is the way in any case.

the problem is that since eval is still there, the moment our library is evaluated (for whatever reason) rather than injected as global script the window, global, or this reference could be different :(

as for caller - I do find the concept of removing it appealing - why should a function know who called it? if we want our function to gain context, we should design it to use apply - which is a much clearer notion of passing context.I agree with your general sentiment that a language should not impose coding styles on it's users, which is the real problem with strict mode. That is especially the case with 'with' - which is an extremely strong operator when used correctly (for example when writing templating engines).

on the up side - I don't really see a scenario where browser will dump the 'non-strict' versions any time soon - the same way we can still open HTML3 pages

I must say I'm rather opposite to most of your points. I'm not gonna say that I'm enlightened with strict mode but I find it very useful.

I don't miss at all anything that strict mode forbids and basically all stuff that it forbids to me was or bad practice or effect of mistake - now with strict mode this can be quickly taken out.

If I mistakenly declared global variable, or put same name for two properties in object literal I'd like to get that quickly, strict mode gives me that, and if tests for my code have full coverage, then I can be sure I spot all such errors before production.

Another example:delete b;

I think it's very sane to throw error on that.Why would you write such code? The thing is that you would write that only by mistake, in ES3 it's silent, in strict mode it's error. I think it's helpful.Imagine you typed comma instead of dot:

delete a,b;

In ES3 it may take you a while to track this error, in ES5 it's instant and obvious.

The only issue I find with strict mode is strictness on production environment. What if mistakenly I declared my variable as global, and my unit tests didn't cover it ? On production with strict mode it will crash, while in ES3 it will silently pass, which for production should be way to go.

hey Medyk, I use "use strict" since the very beginning.All I am saying is that it did not change a thing on my daily code, neither improved.

I rather wonder why developers were making those mistakes before but Errors are surely welcome.

What is not welcome, as example, is that I have often used "arguments" as named function argument because arguments reference and magic is going to disappear at some point.

I have always thought engines could have been clever enough to get rid of arguments but they rather made it protected reference.

This and other minor gotchas I am not that happy about do not mean we should not use "use strict" ASAP ... actually, I would like to have it by default and eventually deactivate it only if absolutely necessary ( I don't like tons of libraries with redundant "use strict" everywhere )

Btw, this post was a point2point summary of that specs page, it's not about good or bad, it's about explaining them and comment them with my personal opinion.