An Interest In:
Web News this Week
- March 21, 2024
- March 20, 2024
- March 19, 2024
- March 18, 2024
- March 17, 2024
- March 16, 2024
- March 15, 2024
Does JS function's 'this' have a default value?
Disclaimer
There are 1000000 articles about this in JS. I think it is perfectly fine to add one more.
Second parameter of Array.prototype.map
Recently I have checked the MDN page about .map() method of the array prototype and met one paragraph witch hooked my attention:
where thisArg is a second parameter of .map() method (1)
The second sentence says - "Otherwise, the value undefined will be used as its this value." So, let's do a quick test and pass inside .map() only a callback:
[1,2,3].map(function(){console.log(this)})// globalObject// globalObject// globalObject
It seems confusing as this value is a global object and not undefined when a callback is executing. Actually it is expected as the callback is executed in non-strict mode. Why then the phrase says undefined?
Nevertheless, the phrase makes sense, especially, if we pay attention to the line - "The this value ultimately observable by callbackFn".
So, what "ultimately observable" does mean?
Default value of function's this
Let's create a simplest function ever and try to call it by .apply() method. The .apply() method allows us to set this value explicitly and let's set this as undefined
function f (){ console.log(this)}f.apply(undefined)// globalObject
So, it is possible to conclude that function f ultimately observes globalObject value in this and not undefined value we explicitly pass. In my opinion we may compare such behaviour with default function parameters:
function f(a=globalObject){ console.log(a)}f();
Spec time!
Now it is time to open the ES specification just to be sure that we do not miss any cases.
I really would like to make your life easier, so there is an abstract operation OrdinaryCallBindThis which is responsible for default this value. There are several steps but 2 of them are main:
Let's pay attention to 2 variables on the pic:
- thisArgument - is a passed value in a function;
- thisValue - is an ultimately observable value by a function;
Step 5 says that if our function is called in strict mode then thisValue becomes thisArgument and default value for this is not applicable.
function f (){ 'use strict' console.log(this)}f.apply(undefined)// undefined
Step 6 says that if our function is called in non-strict mode and thisArgument equals to undefined or null then thisValue (actual value of this inside function) is globalObject (globalEnv.[[GlobalThisValue]] on the pic is just a global object).
function f (){ console.log(this)}f.apply(undefined)f.apply(null)// globalObject// globalObject
So null value is also substitute with globalObject default value.
Also it is worth to have a look at 6.b which is also valid for non-strict mode. There is call of toObject() operation which creates wrapper objects (String, Number, etc) for primitive values of thisArgument:
function f (){ console.log(this)}f.apply('')// String{''}
Therefore function's this value is always an object type for non-strict mode.
Conclusion
Each time you call a function in JS you pass a this value in it. Even if you call a function like f(); you still implicitly pass undefined value. A strict mode function accepts any this value without any modifications. A non-strict function substitutes undefined and null values with global object and also transform all primitive values in objects.
Feel free to use that conclusion to win a heart of your next interviewer.
P.S.
There is one my old post about this value in a setTimeout callback. In a browser callback's this is always window and it does not depend on strict/non-strict mode. The reason is that setTimeout method passes window object not undefined as this when executes a callback. Non-strict default substitution just does not work as thisArgument is neither undefined nor null.
(1) - Array.prototype.map() method has a second optional parameter:
// Callback functionmap(callbackFn)map(callbackFn, thisArg)
that second parameter may be used instead of .bind() method for a callback function.
Original Link: https://dev.to/smlka/global-object-is-just-a-default-value-of-js-functions-this-14hp
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To