Introduction
After ES6 was released, I have seen that many developers are still unaware of the recently added functions of the Array object. Therefore, I decided to create this article to spread the information and hope that many will benefit from it.
Background
This article isn’t about an introduction to JavaScript arrays but more of studying the newly added functions of the
Array object. I do suggest that you make a
Google search if you are a beginner. Moreover, in my opinion, these added functions do have an aim. And, one of those is to make our lives easier and be productive when working with the Array object. Lastly, if you have a good understanding of arrays, you’ll be comfortable reading this article.
ECMAScript 6 Enhanced Arrays
As we have mentioned, the ECMAScript 6 (ES6) has added new methods to the global Array object. Therefore, will be discussing the following methods:
- Array.from()
- Array.of()
- copyWithin()
- fill()
- find()
- findIndex()
- entries()
- keys()
- values()
So let’s get started then. I hope you are excited.
The Array.from() Method
This is a static method that returns a new Array instance from an iterable object. However, you can also pass an “Array-like Object” in the first parameter. If you have no idea about it yet, it will be discussed as part of this section.
Syntax
Parameters
- arrayLike – is the reference of an iterable object.
- mapFn – is optional, and acts as a callback known as map-function.
- thisArg – is optional too, and is the value of this inside the map-function.
Let us see an example below.
- let result = Array.from('JavaScript', (val, indx) => `[${indx}]` + "=>" + val.toUpperCase());
-
- console.log(result);
Output
As you can see, the example above is easy to follow.
Map Function
- This is the 2nd parameter, if provided, it will act as a mapping callback when invoked. And, it transforms each value from the source to the returned target.
- This is similar to Array.prototype.map() method.
Now, why not see another example don’t you think? And, why not put the Array.from() inside an Object. Thereby, we can see how the mapping callback function and the 3rd parameter this behaves.
- const manager = {
- isBadManager: true,
- doBadStuff: function (items) {
- return Array.from(items, function (val, indx) {
-
- if (this.isBadManager) {
- console.log(`${indx + 1}. ${val[0].toUpperCase()}${val.substr(1)}`);
- }
- }, this);
- }
- }
-
-
-
-
-
-
- manager.doBadStuff(['that\'s my idea','micromanage']);
Again, easy to follow example. Now, let’s take it up a notch. And, let’s focus a bit more on the 1st parameter of the
Array.map() which is the array-like object (
arrayLike).
What is an Array-like Object?
Usually, you’ll experience some objects in JavaScript that looks like an array, commonly known as “Array-like Object”. Confused? Don’t be. It is an object which has a length property of a non-negative integer and it got some indexed properties.
Let us see an example below.
- let arrLike1 = {
- length: 3,
- 0: "Jin",
- 1: "Vincent",
- 2: "Necesario"
- };
That’s it? Yes.
Now, let’s look at how we can convert the arrLike1 variable into a real array using Array.from().
- let resultArray2 = Array.from(arrLike1);
- console.log(resultArray2);
-
NodeList
A NodeList is another example of an array-like object. Even I struggled with NodeList I thought it was an array but it is not.
NodeList and Arrays are completely different things.
OK, so what’s a NodeList? A NodeList object is a collection of DOM nodes that was extracted from the HTML document when using a browser API such as querySelector() and/or querySelectorAll().
Now, that we have an idea of what a NodeList is.
Let’s try to convert a NodeList to an array with the use of Array.from().
-
- <body>
- <div>
- <p>Hello World 1</p>
- <p>Hello World 2</p>
- <p>Hello World 3</p>
- </div>
- </body>
-
-
-
-
-
-
-
-
-
-
-
-
- window.addEventListener("DOMContentLoaded", function (event) {
-
- let elements = document.querySelectorAll("div p");
-
- console.log(elements);
-
-
- console.log(elements.length)
-
- console.log(typeof (elements));
-
-
- console.log(elements instanceof NodeList);
-
-
- console.log(elements instanceof Array);
-
- let arrayParagraphs = Array.from(elements);
-
- console.log(arrayParagraphs);
-
- });
-
-
-
Output
Now, that we are familiar with the array-like object and we have seen how to convert into a real array.
The next concept we need to understand is how to avoid empty slots.
Avoiding Empty Slots
Empty slots? What are they?
Basically, when you create an array to a certain length without specifying the values per index you’ll have an empty index also known as an empty slot.
Let us see an example below.
- const arrWithEmptySlots = [];
- arrWithEmptySlots.length = 5;
- arrWithEmptySlots[0] = "Jin";
-
-
- console.log(arrWithEmptySlots);
Output
How can I check for empty slots?
We can use the in operator to check if the array has a key. Moreover, it returns a boolean value, false for empty slots but true for slots with value, including the undefined value.
Let us see an example below.
- const arrWithEmptySlots = [];
- arrWithEmptySlots.length = 3;
- arrWithEmptySlots[0] = undefined;
- arrWithEmptySlots[1] = "Jin";
-
- console.log(0 in arrWithEmptySlots);
- console.log(1 in arrWithEmptySlots);
- console.log(2 in arrWithEmptySlots);
- console.log(3 in arrWithEmptySlots);
-
-
-
-
-
-
- for (let slot in arrWithEmptySlots) {
- console.log(slot);
- }
What’s this empty slot got to do with the Array.from() method?
If you wanted to produce an array initialized to a certain length without empty slots, Array.from() solves that.
Let us see an example below.
- const arrayWithEmptySlots_2 = [];
- arrayWithEmptySlots_2.length = 5;
-
- const results = Array.from(arrayWithEmptySlots_2);
-
-
- console.log(results);
Before we move to the next section.
We can then conclude that Array.from() not only creates a new Array instance from an iterable object.
It also accepts an “Array-like Object” that will be converted into a real array and helps us to avoid empty slots.
The Array.of() Method
Mostly, everyone understands that an Array constructor is utilized to create an Array-object. Moreover, Array.of() method comes in as an alternative to the Array constructor and we are going to see why, in this section.
Syntax
Parameters
- [] – elements used to create the array.
Let us see some examples below.
Create a new Array constructor and pass more than one argument.
- let cars = new Array("Toyota", "Mitsubishi", "Nissan", "Honda");
-
-
- console.log(cars.length);
-
- console.log(...cars);
-
- let customers = new Array({ name: "Jin" }, { name: "Vincent" }, { name: "Necesario" });
-
-
- console.log(customers.length);
-
- console.log(...customers);
-
- let luckyNumbers = new Array(23, 29, 32);
-
-
- console.log(luckyNumbers.length);
-
- console.log(...luckyNumbers);
Create a new Array constructor and pass one argument. And, let us see the glitch.
- let car = new Array("Toyota");
-
- console.log(car);
-
- let customer = new Array({name: "Jin"})
-
- console.log(customer);
-
- let luckyNumber = new Array(23);
-
-
-
- console.log(luckyNumber.length);
-
-
-
- console.log(luckyNumber);
A Small Glitch?
Did you spot the difference? Let’s take for instance the luckyNumber variable, it resulted differently compare to the variables car and customer.
Remember that when you have passed one argument with a number value.
It is creating an empty array with a length property equal to the number and produces empty slots based on the length property.
Is this a glitch? Maybe yes or maybe no. In order for us to avoid this issue, we can use the Array.of() method.
Let us see an example below.
- let superLuckyNumber = Array.of(23);
- console.log(superLuckyNumber);
Therefore the
Array.of() method was introduced to resolve the issue.
Let me know your thoughts in the comment section. Thanks in advance.
The copyWithin() Method
The copyWithin() method is used to copy the sequence of values of the array to a different position in the array.
Syntax
Parameters
- target – is the index where to copy elements.
- start – is optional, and this is the index position where to start copying from.
- end – is optional, and this is the index where to actually end copying elements.
If start index is negative, it’s treated as length of array plus start-index ([].length + start). Same as with end index ([].length + end).
Let us see an example below.
- let presidents1 = ["Donald Trump", "Barack Obama", "George Bush", "Bill Clinton"];
- let presidents2 = ["George H. W. Bush", "Ronald Reagan", "Jimmy Carter", "General Ford"];
-
-
-
- console.log(presidents1.copyWithin(0, 1));
-
-
-
-
- console.log(presidents2.copyWithin(1, 2, 3));
Easy to follow isn’t? Let’s move to the next section.
The fill() Method
The fill method actually fills (entirely or partially) all the elements of the array from the start index to the end index with the given value. Moreover, the start and end index are optional; therefore if they are not provided then the entire array is filled by the value you passed.
Syntax
Parameters
- value – the value to fill the array.
- start – optional, and is the start-index.
- end – optional, and is the end-index.
If you have seen the issue of the Array constructor. Likewise, we can use this method to set the values for all the empty slots of the array.
You can do this as long as your target is to initialize an array with defined length and with no empty slots.
Let us see an example below.
- let arryLenOf5 = new Array(5).fill(undefined);
-
- console.log(arryLenOf5);
- let arryLenOf3 = new Array(3).fill(0);
-
- console.log(arryLenOf3);
Let us see some examples again.
-
- console.log([29, 23, 5, 26, 16, 21].fill(29));
-
-
- console.log([29, 23, 5, 26, 16, 21].fill(30, 1));
-
-
- console.log([29, 23, 5, 26, 16, 21].fill(31, 2, 5));
-
If start index is negative, it’s treated as length of array plus start-index ([].length + start). Same as with end index ([].length + end).
-
- console.log([29, 23, 5, 26, 16, 21].fill(31, -2));
-
-
- console.log([29, 23, 5, 26, 16, 21].fill(31, 1, -2));
-
Easy to follow isn’t? Let’s move to the next section.
The find() Method
Before we go in-depth with the find() method will step back a bit. And answer: “What it does really resolves?”.
Syntax
Parameters
- callback – a callback function that executes on each value in the array.
- thisArg – is optional, Object to use as this inside the callback.
The indexOf Method
Usually, the first thing that comes to mind when searching for a value in an array has been the use of the indexOf() method.
Let’s see an example below.
- let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
- console.log(nums.indexOf(9));
- console.log((nums.indexOf(7) !== -1));
- console.log((nums.indexOf("9") == 0));
- console.log((nums.indexOf("Jin Vincent Necesario") !== -1));
However, sometimes programmers forgets that this method requires a strict comparison. In my opinion, that’s why they (programmers) uses the some() method.
The some() Method
This method works by invoking a function callback for each element until one returns a true or truthy value, and finally, it stops.
The benefit is you have control over the comparison of values not unlike the indexOf() method.
Let us see an example below.
- let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
- console.log(nums.some((num) => num == "9"));
- console.log(nums.some((num) => num === "9"));
Now, the drawback of the some() method is you can only get the boolean values true or false, if a suitably matched value was found, but not what the actual value matched.
What does find() Method resolve?
The find() method resolves that issue. It works like the some() method, except once the callback returns its value, the actual array value is returned.
Therefore, the find() method returns an array element. Only, if it satisfies the provided expression passed to the callback function. Otherwise, it returns undefined.
Let’s see an example below.
- let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
- console.log(nums.find((num) => num == "9"));
- console.log(nums.find((num) => num === "9"));
Why not another example with the complete parameters?
- let num = 5;
- let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
- let result = nums.find(function (value, index, array) {
-
- console.log(`The num[${index}] is equal to ${value} ${this}`);
- return value === parseInt(this);
- }, num);
- console.log(result);
The findIndex() Method
This is almost similar to the find() method. However, it returns the index of the array element instead of the element itself.
Syntax
Parameters
- callback – a callback function that executes on each value in the array until the function returns true. Otherwise, undefined, which indicates that element wasn’t found.
- thisArg – is optional.
Going back to the
indexOf() method, we have seen that’s there no control over its matching logic. Thus,
findIndex() saves the day.
Let’s see an example below.
- let num = 5;
- let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
- let result = nums.findIndex(function (value, index, array) {
-
- console.log(`The num[${index}] is equal to ${value} ${this}`);
- return value === parseInt(this);
- }, num);
- console.log(result);
Now, that we have a good background on the find() method and the similarities of find() and findIndex().
Let’s have another example, a customized search.
- const houses = [
- { length: 22, width: 288, measurement: 'ft' },
- { length: 182, width: 532, measurement: 'ft' },
- { length: 12, width: 152, measurement: 'ft' },
- { length: 20, width: 30, measurement: 'ft' },
- { length: 12, width: 152, measurement: 'ft' }];
- let indexResult = houses.findIndex((house) => (house.length * house.width) === 600);
- console.log(indexResult);
When To Use find() and findIndex() Method?
- Don’t treat the findIndex() method just like on how we use the indexOf() method for comparison because we have the some() method that returns the boolean value we need.
- Don’t use the findIndex() method to get the matched value because that’s what the find() method for.
- Use the indexOf() method if you need a strict match.
- Use the findIndex() if you need the index of a more customized match.
The entries() Method
This method returns an iterable object. Moreover, the actual returned object is an Array Iterator that contains key/value pairs for each index of the array.
Syntax
Let us see an example below.
- let fruits = ['mango', 'apple', 'dragon fruit'];
-
- console.log(fruits.entries());
-
-
-
- let fruitEntries = fruits.entries();
-
-
-
-
-
-
- for (let current of fruitEntries){
- console.log(current);
- }
-
-
-
-
-
-
- for(let [index, element] of fruits.entries()){
- console.log(index, element);
- }
The keys() Method
This method is similar to the entries() method. However, the object returned contains the keys for each index in the array.
Syntax
Let us see an example below.
- let fruits = ['mango', 'apple', 'dragon fruit'];
-
- console.log(fruits.keys());
- let fruitKeys = fruits.keys();
-
- console.log(...fruitKeys);
The values() Method
This method behaves similarly to [].keys() and [].entries(). However, the difference, this method returns the value of each key in the array.
Syntax
- let fruits = ['mango', 'apple', 'dragon fruit'];
-
- console.log(fruits.values());
- let fruitKeys = fruits.values();
-
- console.log(...fruitKeys);
Summary
In this post, we have learned the new
Array-object methods of the JavaScript(ES6) language. Moreover, we have tackled how these methods work, why it’s added, and what issue/issues it resolves. Overall, we have seen the history and benefits of these methods. I hope you have enjoyed reading this article, as much as I have enjoyed writing it. Stay tuned for more. This article was originally written and posted
here. Until next time, happy programming!