Categories
Lodash

Learning JavaScript by Implementing Lodash Methods — Object Traversal

Spread the love

Lodash is a very useful utility library that lets us work with objects and arrays easily.

However, now that the JavaScript standard library is catching up to libraries such as Lodash, we can implement many of the functions in simple ways.

In this article, we’ll look at how to implement some methods for traversing through object keys.

forOwn

The Lodash forOwn method iterates through an object’s own enumerable string keyed properties and run the iteratee function on each property.

The iteratee takes 3 arguments, which are value , key and object . where value is the value of the property that’s being looped through. key is the property key string, object is the object that’s being traversed.

We can get all the object’s keys with the Object.keys method as an array, so we can loop through the keys as follows:

const forOwn = (obj, iteratee) => {
  for (const key of Object.keys(obj)) {
    const result = iteratee(obj[key], key, obj);
    if (result === false) {
      break;
    }
  }
}

In the code above, we called Object.keys with obj to get the own keys of obj . Then we call iteratee with the value by referencing obj[key] as the 1st argument, key as the 2nd argument, and obj as the 3rd argument.

iteratee is called on each iteration and its return value is set as the value of result .

Then when we call it as follows:

function Foo() {
  this.a = 1;
  this.b = 2;
}

Foo.prototype.c = 3;

forOwn(new Foo(), (value, key) => console.log(key));

We get a and b from the console log output since a and b are the Foo ‘s instance’s own property, but c is an inherited property from Foo ‘s prototype.

forOwnRight

Lodash’s forOwnRight method is like forOwn except that it loops through the object’s keys in reverse order.

We can just change forOwn ‘s implementation slightly by calling reverse on the array returned by Object.keys to loop through the keys in reverse.

For instance, we can implement that as follows:

const forOwnRight = (obj, iteratee) => {
  for (const key of Object.keys(obj).reverse()) {
    const result = iteratee(obj[key], key, obj);
    if (result === false) {
      break;
    }
  }
}

In the code above, we have the same implementation as forOwn except that we called reverse after Object.keys .

Then when we call it as follows:

function Foo() {
  this.a = 1;
  this.b = 2;
}

Foo.prototype.c = 3;

forOwnRight(new Foo(), (value, key) => console.log(key));

We see b then a logged in the console log output.

functions

The functions method returns the array with the property names of own properties that are function valued.

We can implement that ourselves by checking whether the given property has type function and put it in the returned array.

For instance, we can do that as follows:

const functions = (obj) => Object.entries(obj).filter(([key, value]) => typeof value === 'function').map(([key]) => key);

In the code above, we used Object.entries to get the key and value of each property of obj as a nested array with each entry as an array of the key and value.

Then we called filter on what’s returned by Object.entries by destructuring the given key and value on each entry, and then return whatever value has the 'function' type by checking value with the typeof operator.

Next, we called map on with the key destructured from the array to return the keys only and put them in the returned array.

Then when we have a Foo constructor and call it with the Foo instance as follows:

function Foo() {
  this.a = () => 'a';
  this.b = () => 'b';
}

Foo.prototype.c = () => 'c';

const result = functions(new Foo());

We get that result is [“a”, “b”] since in the Foo instance, only 'a' and 'b' are function valued own properties.

Conclusion

To implement the forOwn and forOwnRight Lodash methods, we can use the Object.keys method to get all the keys and then use the for...of loop to loop through the own keys of the given object.

The functions method can be implemented by calling Object.entries to get the keys and values of an object as an array.

Then we can call the filter method with the typeof operator to check the ones that value type 'function' . Then we can get the keys of the function valued properties and return an array with them with map.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *