I read the following on a website:
Use-strict has an advantage. It eliminates this coercion. Without strict mode, a reference to a this value of null or undefined is automatically coerced to the global. This can cause many headfakes and pull-out-your-hair kind of bugs. In strict mode, referencing a a this value of null or undefined throws an error.
What exactly does this mean? What does use-strict have to do with this
coercion?
The purpose of "use strict" is to indicate that the code should be executed in "strict mode". With strict mode, you can not, for example, use undeclared variables. The numbers in the table specify the first browser version that fully supports the directive. You can use strict mode in all your programs.
'use strict'; When a JavaScript engine sees this directive, it will start to interpret the code in a special mode. In this mode, errors are thrown up when certain coding practices that could end up being potential bugs are detected (which is the reasoning behind the strict mode).
Is use strict necessary? The strict mode is no longer required since the release of ES2015, which fixes most of JavaScript's confusing behavior with a more robust syntax. It's just good to know because you might find it in legacy projects that still used it.
By changing errors to throw errors, strict mode removes certain JavaScript silent errors. Strict mode repairs mistakes that make it difficult for JavaScript engines to perform optimizations. (It can sometimes execute faster than identical code that's not strict mode.)
When you call a function in javascript, 'this' will refer to different things depending on the context:
If the function has been bound, the 'this' will be set to whatever
it was bound to, e.g. fn.bind(x)()
If you invoked the function using fn.call(x)
or fn.apply(x)
, the
this will be set to x.
If the function was defined using arrow notation, then the this
will be whatever was defined to be this
when the function was
defined.
If you call the function with thing.fn()
, the this
is what is
before the '.', in this case 'thing'.
If you're in a constructor, called with new
then this
refers to
the new object under construction.
If you are just calling a bare function, that isn't on any object,
that isn't bound, that isn't an arrow function and you're calling it
in the straightforward way, without using call or apply, then the
this
will refer to the global object if you are not in strict mode,
and undefined if you are in strict mode. This is what is referred to
as 'this coercion' by the quote.
That's why, if you open a browser console and type
Function('console.log(this)')()
the console will output the Window which is the global object in the browser. However if you open the console and type
Function('"use strict";console.log(this)')()
the console will log undefined
.
I'm using the Function constructor here, because it's a way to force the use of non-strict mode regardless of the situation it appears in - so these examples should still work, even if you run them from inside a file or console operating in strict mode.
this
coercion can be the the most convenient way of getting the global object, i.e.
const global = Function('return this')()
works in both the browser and node, even in strict mode.
But most of the time, you want to fail fast, and having functions that you expected to operate on specific kinds of instances actually operate on your global object can mess things up badly. Having attempts to write something to or read something from this
throw exceptions when it isn't defined is almost always better than reading and writing to the global object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With