Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

on this MDN page [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find] there is 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 is definitely an array (we are augmenting Array.prototype) so why make sure length is numerical, and why is Object() used?

like image 641
M.J. Saedy Avatar asked Jun 12 '14 11:06

M.J. Saedy


People also ask

What is prototype array prototype?

Definition and Usage prototype allows you to add new properties and methods to arrays. prototype is a property available with all JavaScript objects.

Can I use array prototype at ()?

Array.prototype.at() The at() method takes an integer value and returns the item at that index, allowing for positive and negative integers. Negative integers count back from the last item in the array.

What does array prototype do?

The JavaScript array prototype constructor is used to allow to add new methods and properties to the Array() object. If the method is constructed, then it will available for every array. When constructing a property, All arrays will be given the property, and its value, as default.

How do you find the object of an array?

Answer: Use the find() Method You can simply use the find() method to find an object by a property value in an array of objects in JavaScript. The find() method returns the first element in the given array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.


1 Answers

The fundamental answer is that the polyfill is just faithfully implementing Step 1 and Step 4 of the algorithm in the ES6 draft spec (§22.1.3.8 as of the May 22 draft).

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

...

4. Let len be ToLength(lenValue).

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

And as it's possible to use non-object values for this nowadays (via Function#call and Function#apply, or by just calling the function directly in strict mode), Step 1 makes sense.

since this is definitely an array (we are augmenting Array.prototype) so why make sure length is numerical, and why is Object() used?

But we don't know that this is an array. See this note from the current ES6 draft spec:

The find function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the find function can be applied successfully to an exotic object that is not an Array is implementation-dependent.

You'll find that note on nearly all of the predefined functions assigned to prototypes.

E.g., you can use them for other things, either by assigning them to objects or other prototypes directly:

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

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

So suppose I wanted to use Array#find on an arguments object. arguments is, of course, array-like but not an array. So I might do this:

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

A more famous example (not involving find) is using slice to convert array-like objects into arrays:

function foo() {
    // Turn the `arguments` pseudo-array into a real array
    var args = Array.prototype.slice.call(arguments, 0);
}
like image 139
T.J. Crowder Avatar answered Oct 29 '22 11:10

T.J. Crowder