Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript's Object(this) usages in polyfills?

Tags:

javascript

I saw here the Array.prototype.forEach()'s polyfill and I have a question about its implementation :

/*1*/   if (!Array.prototype.forEach)
/*2*/   {
/*3*/     Array.prototype.forEach = function(fun /*, thisArg */)
/*4*/     {
/*5*/       "use strict";
/*6*/   
/*7*/       if (this === void 0 || this === null)
/*8*/         throw new TypeError();
/*9*/   
/*10*/       var t = Object(this);
/*11*/       var len = t.length >>> 0;
/*12*/       if (typeof fun !== "function")
/*13*/         throw new TypeError();
/*14*/   
/*15*/       var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
/*16*/       for (var i = 0; i < len; i++)
/*17*/       {
/*18*/         if (i in t)
/*19*/           fun.call(thisArg, t[i], i, t);
/*20*/       }
/*21*/     };
/*22*/   }

Looking at line #10 : why did they use Object(this) ?

As I searched its usages I saw this :

The Object constructor creates an object wrapper for the given value. If the value is null or undefined, it will create and return an empty object, otherwise, it will return an object of a type that corresponds to the given value. If the value is an object already, it will return the value.

So they wanted to check if it's null || undefined .

Ok , But they already checked it in lines #7-#8 !

Question :

What is the reason (which I'm missing) that they used Object(this) ?

like image 619
Royi Namir Avatar asked Oct 02 '22 05:10

Royi Namir


1 Answers

So they wanted to check if it's null || undefined.

No. The purpose is

The Object constructor creates an object wrapper for the given value. If the value is null or undefined, it will create and return an empty object, otherwise, it will return an object of a type that corresponds to the given value. If the value is an object already, it will return the value.

It will convert primitives to objects, like "foo" to new String("foo").

This is strictly not really necessary, because the property access of .length and the indices would convert a primitive to an object anyway. It would make a difference however when the third callback parameter is used, you can expect an object there (and the same one for each invocation).

What is the reason that they used Object(this)?

Mostly to reproduce step #1 of the forEach spec, which is to call ToObject on the argument. In the spec this is required to be able to use [[Get]] and [[HasProperty]] internal methods on it.

Also, by converting a primitive to an object only once you gain speed.

like image 79
Bergi Avatar answered Oct 05 '22 12:10

Bergi