What is .apply() and a unpacked array?


What is .apply() and unpacked array. And i dont even understand spread oprerator.
If we cannot pass array in Math.max, then how can …args be passed as it is also an array ?

var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr); // returns 89

-Apply is method on function object (max is function(method) on Math object.
What apply does… It takes array (arr in this case) and “spreads” all items (6, 89, 3, 45) from it into Math.max, and calls it. So it is same as you would call it like this: Math.max(6, 89, 3, 45).

…Oh and applys first argument is keyword this(object that calls the function, which is in this case Math, but its a bit over the top i think, no need to worry about that for this, for now. If you’re interested i could try to explain those “explicit bindings”(call, apply, bind).

Spread operator
-Spread is es6 thing. with spread you doing same thing in this case. it just “spreads” array into Math.max.
But spread is quite useful in hm lets say you have two arrays and you want to combine them into one array, you can use something like this:

var arr1 = [1, 2];
var arr2 = [3, 4];

var newArr = [...arr1, ...arr2];

newArr is [1,2,3,4]

1 Like

That’s not what apply does, it does this in the challenge because apply was used to mimic the use of a spread operator. Apply in itself is used to call a function with a “this” of another object.

As for the spread operator, it helps you “spread” elements of an array as a single argument. If you have a function that expects some arguments, and you have those arguments stored in an array, you can simply spread them using ...arrayName.

In the challenge, apply is used to do a similar thing that spread operator does, it takes the second argument (the array) and calls the function with it. The first argument is “null” because you don’t care about assigning the function a new “this” in this case, you just want the arguments of the array (second argument).

Example use:

const todaysDate = [`8th`, `December`, 2018]

const todayIs = (day, month, year) => {
  console.log(`Today is ${day} of ${month}, ${year}`)

Few ways to call the function

1. todayIs(`8th`, `December`, 2018) // "Today is 8th of December, 2018"
2. todayIs(...todaysDate) // "Today is 8th of December, 2018"
3. todayIs.apply(null, todaysDate) // "Today is 8th of December, 2018"

As you can see, in each case the output will be the same.

1 Like

Thanks. That cleared my confusion. Plus, It would be really helpful for me if you can explain the .filter() and the rest operator.

What does the .filter do. And what is a rest operator ?

Rest and spread operator are the same (...) the only thing that distinguishes them is where you use them.

  • Spread is used to “spread” the elements of an array or object
  • Rest is used to catch “the rest” of the arguments of a function

Here is an example:

const theNames = (name1, name2, ...names) => {
  console.log(`First name: ${name1}. Second name: ${name2}. Rest of the names: ${names}.`)

Note that in this case, rest operator (...) has been used when declaring the function, as a parameter. Whatever will be passed into the function after the first 2 arguments (or however many you specify before using the rest operator) will be stored in an array with the variable name of names (in this case).

Calling the function:

theNames(`Bob, Job, John, Eva`)
will output "First name: Bob. Second name: Job. Rest of the names: John,Eva."

“John,Eva” because when console logging like this, the array will automatically be converted into a string. Doesn’t have anything to do with the rest operator.

Think it covers it all.

As for the filter, it’s a very simple one. Array.filter() takes a callback as an argument, that callback gives you access to the currently iterated element of the array, which I’ll call below myArrayElement

myArray.filter( (myArrayElement) => {
  return myArrayElement > 5

Filter will iterate through the entire array to find what matches your conditions for being filtered, here the condition is just being greater than 5, but you’re free to use it for more than just arrays of numbers. If the return is true the value is filtered, otherwise it’s not.

One note - original array will not be changed so you need to store the filtered values in a new array, like this:
const newArray = myArray.filter.....

You should check this documentation. You’ll find an article for pretty much everything in javascript with good explanations and examples.


Filter is as called “higher order function”. Higher order function either takes another function as argument or returns function… or does both.
You can use filter to filter out data you dont need from an array.

Lets say you have const arr = [1,2,3]; and you want to remove number 2, because… them filthy even numbers, right?
You would use something like this:

const dontLetTwoIn= arr.filter(function(number) {
  return number !== 2;

dontLetTwoIn = [1,3].
Filter filters out values from array you dont want. But it does not mutate original array.
So in this case your arr array still remains the same. arr = [1,2,3].

Its convenient to use arrow function syntax with those methods. Previous code would look something like this with arrow function.

const dontLetTwoIn= arr.filter(number => number !== 2);

Rest is useful when you doesn’t know number of paramaters you want to have in an function.
It gets all arguments passed to the function into an array.

function alotParams(...params) {
alotParams("a", "b", "c", "d"); 

logs:[ ‘a’, ‘b’, ‘c’, ‘d’ ]

or when you want to get rest of the arguments, beside ones you expect:

function alotParams(firstArg, secondArg,...params) {
alotParams("a", "b", "c", "d");

logs: [ ‘c’, ‘d’ ]

1 Like

Yeah true that. But i was thinking that he/she doesn’t need that extra keyword this binding complexity at this point. I think OOP section is yet to come with call, apply and bind. Or maybe im wrong, i dunno. But tru det, tru det…
Thanks for clearing that up.

What exactly is .apply() then ?

“Execute a function by applying these arguments (provided as an array) to it”

function add(a, b) {
  return a + b;

These give exactly the same result:

add(1, 2)
add.call(null, 1, 2)
add.apply(null, [1, 2])
1 Like