According to the MDC, the ECMA-262, 5th edition gives the implementation of forEach as:
if (!Array.prototype.forEach)
{
Array.prototype.forEach = function(fun /*, thisp */)
{
"use strict";
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== "function")
throw new TypeError();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in t)
fun.call(thisp, t[i], i, t);
}
};
}
Can anyone tell me what the line "var t = Object(this)" is doing? How does Object(this) differ from plain this? And what work is that difference doing here?
The Mozilla implementations just try to emulate exactly the steps that are described in the specification, Object(this);
emulates the first step, calling the ToObject
internal method:
From Array.prototype.forEach
15.4.4.18:
....
When the forEach method is called with one or two arguments, the following steps are taken:
Let O be the result of calling ToObject passing the this value as the argument.
Let lenValue be the result of calling the [[Get]] internal method of O with the argument "length".
Let len be ToUint32(lenValue).
....
Calling the Object constructor as a function behind the scenes it performs type conversion, internally as described in 15.2.1.1 the ToObject
method is called.
There are more things like this if you look carefully, for example, the line:
var len = t.length >>> 0;
They are emulating a call to the ToUint32 internal method, as described in the step 3, using the unsigned right shift operator (>>>
).
Edit: The previous lines answer why the Mozilla implementation does it in this way.
You might wonder why the ECMAScript spec. needs to call ToObject
, check back the Step 2, and it will start to seem obvious:
- Let lenValue be the result of calling the [[Get]] internal method of O with the argument "length".
The spec. needs to ensure that the this
value used when the function is called is an object, because primitive values don't have any internal methods, an as you can see on the step 2, the [[Get]](P)
internal method is needed, to get the value of the length
property.
This is done because for strict functions (and also for built-in functions), you can set primitive values as the function's this
value, e.g.:
(function () {"use strict"; return typeof this; }).call(5); // "number"
While for non-strict functions, the this
value is always converted to Object:
(function () { return typeof this; }).call(5); // "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