Update
Thanks for your help guys, I was unaware of the things to be aware of when using lambda (fat arrow) functions.
if (window.Array && !Array.prototype.isEmpty)
{
Array.prototype.isEmpty = function ()
{
return this.length === 0;
};
}
console.log("[]", [].isEmpty());
console.log("[1]", [1].isEmpty());
This works now.
Original Question
I have been trying to add the functionality of isEmpty to the Array prototype in javascript to both make my code a little cleaner and also because I want to learn how to do it properly.
I understand that it is advisable to not add your own methods to the existing objects and to make your own, but at this point, I really want to figure out where I am going astray.
I also understand that you can test for an empty array by just doing array.length === 0
.
I have been running into issues where my this
is referring to the window object
instead of the calling array.
This is my code
if (window.Array && !Array.prototype.isEmpty)
{
Array.prototype.isEmpty = (callback, thisArg) =>
{
return this.length === 0;
};
}
console.log("[]", [].isEmpty());
console.log("[1]", [1].isEmpty());
Because this
is a reference to the window object, this.length
is false so no matter what array is calling it, this function returns true.
How do I get this
to refer to the calling object instead of window?
I based on this forEach
shim for NodeList
, I had tried to change my isEmpty function to emulate it because I saw that the forEach was using a callback and my shim wasn't.
NodeList.forEach shim:
if (window.NodeList && !NodeList.prototype.forEach)
{
NodeList.prototype.forEach = (callback, thisArg) =>
{
thisArg = thisArg || window;
for (let i = 0; i < this.length; i++)
{
callback.call(thisArg, this[i], i, this);
}
};
}
Seeing that, this is what I tried to change my function to
if (window.Array && !Array.prototype.isEmpty)
{
Array.prototype.isEmpty = (callback, thisArg) =>
{
thisArg = thisArg || window;
callback.call(thisArg, this.length === 0, 0, this);
};
}
console.log("[]", [].isEmpty());
console.log("[1]", [1].isEmpty());
Unfortunately, this results in an error as the callback function is not defined, I was hoping to send an empty function.
The difference between the two functions is that in the NodeList.forEach
this
is a reference to the NodeList that is invoking forEach
instead of a reference to window
.
From what I can tell, the difference, in the code, between the working NodeList.forEach
and my failing Array.isEmpty
is that with forEach you supply it with a function to act on it, but with isEmpty it's just an empty function call.
I will admit that I don't understand callback functions as well as I would like so I am flailing a bit here. I have tried looking up implementations of isEmpty for JS but most of the responses are just use array.length === 0
, while I will agree this is a good solution, I am trying to push my knowledge boundaries.
Thank you for any insight you can give.