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
.