loading...

Can you implement forEach() correctly?

ashokdey_ profile image AD Updated on ・2 min read

So if you're into JavaScript you may be using forEach() daily. Let's dive deep into and see whether we can implement our own forEach() or not.

forEach() usage

The forEach() method executes a provided function once for each array element. - MDN

const arr = [1, 'ashok', 3, 4]
arr.forEach(el => console.log(el));

So how you'll move forward with implementing your own forEach()?
We have to iterate through the elements with the given callback, Simple!

function myEach(callback) {
  for (let i = 0; i < this.length; i += 1) {
    callback(this[i], i, this);
  }
}

Done? No, you will say we can make it even more realistic by adding it to the Array prototype chain and rule like a King.

Ok, here you go!

Array.prototype.myEach = function myEach(callback) {
  for (let i = 0; i < this.length; i += 1) {
    callback(this[i], i, this);
  }
};

I hope now it's complete. Yay!

Voila!

The above implementation floating around the web is wrong. Find the ECMA Specification here

Know your forEach() better

forEach() calls a provided callback function once for each element in an array in ascending order.

It is not invoked for index properties that have been deleted or are uninitialized1

The above point is something people are not caring about when implementing forEach, to keep things simple, I am skipping the implementation of the 3rd argument this as you can see in the signature arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

Array.prototype.myEach = function myEach(callback) {
  for (let i = 0; i < this.length; i += 1) {
    callback(this[i], i, this);
  }
};

const arr = [1, 'ashok', 3, 4]
// let's delete one of the elements
delete arr[1];

// native
arr.forEach(el => console.log(el));
console.log('-------')
// testing myEach()
arr.myEach(el => console.log(el));

Can you guess the output of the above two? Here is the output:

Code Output

Did you notice that our implementation of the myEach() enumerates on deleted indexes as well?

This has something to do with Prototype Chain I am not willing to cover it here but we can fix this using .hasOwnProperty()

Array.prototype.myEach = function myEach(callback) {
  for (let i = 0; i < this.length; i += 1) {
    if (Object.hasOwnProperty.call(this, i)) {
      callback(this[i], i, this);
    }
  }
};

We can step further and can reduce some code if we can directly run hasOwnProperty() on the current instance i.e this

Array.prototype.myEach = function myEach(callback) {
  for (let i = 0; i < this.length; i += 1) {
    if (this.hasOwnProperty(i)) {
      callback(this[i], i, this);
    }
  }
};

Now you can test this and celebrate that we covered the most distinctive feature of forEach()

Few people are implementing the built-in JS methods Have a look here:

GitHub logo knaxus / native-javascript

Let's implement the built in functions again!

Open Source Love License: MIT

Native JavaScript

Let's implement the built in functions again!

How to Contribute?

  • Try to use native functions and operators
  • Avoid ES6+ features
  • Your solution file should contain the MDN Link of the method you impleneted
  • Your solution file should also contain some introduction about the method and few examples
  • We will provide review to your implemenation
  • Your PR should contain commented test cases
  • We'll add our test cases during the review as well.

Spread

  • Star the repo if you liked the efforts of the initiators
  • Tweet about it.

All the best

I hope you liked it! For digging deeper, here is one more article: https://alligator.io/js/foreach-array-method/

Posted on by:

ashokdey_ profile

AD

@ashokdey_

A Product Engineer, who has crafted products for 3 startups till now. Working on JavaScript stack having a sound UI/UX background

Discussion

markdown guide