Recently I needed a way to detect support for a media query in CSS and Javascript. To detect if a browser supports a certain CSS feature, you can use @supports () { … }, but that doesn’t work for media queries. In this article I’ll show you how you can detect support for media queries […]
Includes, contains or has. Finding things in iterables (lists) in JavaScript
When writing JavaScript, very frequently I need to check if a given thing exists in a list of things. Every single time I need to look up the function that does that for the sort of list I’m working with.
You see, there are three possible options: includes()
, contains()
and has()
and I mix them up all the time. So I’m writing this for my own reference.
The main problem #
Checking if a given thing is in a list is a common action in JavaScript (for me at least). For example, I do it when I need to check if a specific class is applied to an element, or if a return value of a function matches one of multiple values.
The function name to use for this depends on the type of list you’re working with, even though the signature of each function is exactly the same.
You call a function on the list with the item as an argument and you end up with a boolean that tells you if the item is in the list or not:
// returns true or false
list.function(item);
Arrays: includes()
For arrays, you need to use the includes()
function.
classList: contains()
classList is a DOMTokenList
, and those use contains()
.
Map: has()
Maps (and WeakMaps) are relatively new features and act as a sort of “better” object (I won’t go into the differences in this article).
To figure out if a given key exits in a Map, you need to use has()
.
Set: has()
Sets (and WeakSets) are relatively new features and act as a sort of “better” array (Again, I won’t go into the differences in this article).
For Sets you also need to use has()
.
In handy table form: #
Function to use | |
---|---|
Array | .includes() |
classList | .contains() |
Map | .has() |
Set | .has() |
Why is it not all the same? #
Honestly I don’t know.
We can split JavaScript into two parts: language features and DOM APIs. Both of these are made/designed by different groups of people: language features by ECMA and DOM APIs essentially by browser vendors.
classList is a DOM api whereas Array, Set and Map are all language features, which could explain the difference between classList and the rest.
It still doesn’t explain why Array uses includes
and Sets and Maps use has
. I can’t think of a good reason other than oversight during API development, but maybe someone can tell me.
In any case I hope that having written this down will help me remember better, or that it will at least be a quick lookup for me.