Like any kind of apps, JavaScript apps also have to be written well.
Otherwise, we run into all kinds of issues later on.
In this article, we’ll look at ways to improve our JavaScript code.
Things we can do with Higher-Order Functions
We can do various things with higher-order functions.
They let us simplify the code that we repeat.
For instance, instead of writing a loop to loop through an array and push the entries to another array.
Instead of writing:
const names = ["foo", "bar", 'baz'];
const upper = [];
for (let i = 0; i < names.length; i++) {
upper[i] = names[i].toUpperCase();
}
We write use the map
method to do the same thing:
const names = ["foo", "bar", 'baz'];
const upper = names.map((name) => name.toUpperCase());
We called map
with a callback to return each entry as upper case.
It’s much shorter and simpler.
We can make our own higher-order function that takes a callback and do something by taking a callback function to make it do what we want.
For instance, we can write:
const buildString = (n, callback) => {
let result = "";
for (let i = 0; i < n; i++) {
result += callback(Math.floor(Math.random() * 100) + i);
}
return result;
}
const str = buildString(8, String.fromCharCode);
We have created the buildString
function that takes a callback
function.
In the function, we created a for
loop and call the callback
with each iteration of the loop.
callback
is is called with the character code to let us get the character.
And then we can call it by using passing in a number for the length and String.fromCharCode
.
Then str
is 'BO@B1&g’
.
Higher-order functions let us fix any bugs with just once since there’s no repeated code.
And there’s no code spread everywhere in our program.
Use call to Call Methods with a Custom Receiver
We can use the call
method on a function to let us set the value of this
and arguments we call with a function.
For instance, if we have:
f.call(obj, arg1, arg2, arg3);
Then that’s like calling:
f.call(arg1, arg2, arg3);
and setting this
in f
to obj
.
The call
method comes in handy for calling methods that may have been removed, modified or overridden.
For instance, the hasOwnProperty
can be overridden by any object.
We can set:
obj.hasOwnProperty = 1;
Then if we write:
obj.hasOwnProperty("foo");
and we’ll get an error since hasOwnProperty
has been set to 1.
The better to call hasOwnProperty
is to use the call
method.
For instance, we can write:
const dict = {};
dict.foo = 1;
delete dict.hasOwnProperty;
({}).hasOwnProperty.call(dict, "foo");
We created the dict
object with the foo
property.
And we deleted the hasOwnProperty
property from dict
.
Even if we did that, we can still call hasOwnProperty
with an empty object by using the call
method.
The first argument is the value of this
in that we want to call hasOwnProperty
with.
And the argument is the argument for hasOwnProperty
.
Conclusion
Higher-order functions let us abstract out the logic into reusable pieces.
The call
method lets us call a function with whatever value of this
we want.