What's the point of “var t = Object(this)” in the official implementation of forEach?

后端 未结 3 1405
一个人的身影
一个人的身影 2021-01-31 06:05

According to the MDC, the ECMA-262, 5th edition gives the implementation of forEach as:

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun          


        
3条回答
  •  囚心锁ツ
    2021-01-31 06:52

    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:

    1. Let O be the result of calling ToObject passing the this value as the argument.

    2. Let lenValue be the result of calling the [[Get]] internal method of O with the argument "length".

    3. 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:

    1. 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"
    

提交回复
热议问题