Can someone explain this Array.prototype.find () polyfill?

this MDN page [ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find] has this polyfill:

if (!Array.prototype.find) { Object.defineProperty(Array.prototype, 'find', { enumerable: false, configurable: true, writable: true, value: function(predicate) { if (this == null) { throw new TypeError('Array.prototype.find called on null or undefined'); } if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } var list = Object(this); var length = list.length >>> 0; var thisArg = arguments[1]; var value; for (var i = 0; i < length; i++) { if (i in list) { value = list[i]; if (predicate.call(thisArg, value, i, list)) { return value; } } } return undefined; } }); } 

my question is: what are these lines for:

 var list = Object(this); var length = list.length >>> 0; 

since this definitely an array (we are increasing the array Array.prototype), so why is length numeric and why is Object () used?

+8
javascript arrays
source share
1 answer

The main answer is that polyfill just correctly implements steps 1 and 4 of the algorithm in the draft specification ES6 (Β§ 22.1.3.8 of the draft on May 22).

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

...

4. Let len ​​- ToLength (lenValue).

(where ToLength is basically a conversion to a number.)

And how can I use the non-object values ​​for this at the moment (via Function#call and Function#apply , or just calling the function directly in strict mode), step 1 makes sense.

since this definitely an array (we are increasing Array.prototype ), so why consider the length of a number and why is Object() ?

But we do not know that this is an array. See This Note from the Current ES6 Specification:

The find function is intentionally shared; it does not require that its this value be an Array object. Therefore, it can be passed to other types of objects for use as a method. Whether the find function can be successfully applied to an exotic object that is not an array depends on the implementation.

You will find this note for almost all of the predefined functions assigned to prototypes.

For example, you can use them for other things by simply assigning them to objects or other prototypes directly:

 MyNiftyThing.prototype.find = Array.prototype.find; 

... or Function#call or Function#apply .

So, suppose I wanted to use Array#find for the arguments object. arguments is, of course, massive, but not an array. Therefore, I can do this:

 function foo() { var firstObject = Array.prototype.find.call(arguments, function(val) { return typeof val === "object"; }); // ... } 

A more famous example (not related to find ) uses slice to convert objects like an array to arrays:

 function foo() { // Turn the `arguments` pseudo-array into a real array var args = Array.prototype.slice.call(arguments, 0); } 
+10
source share

All Articles