PineNuts0
PineNuts0

Reputation: 5234

JavaScript: Write Function that take an object and an array of functions as input args and return an array

I want to take an object and an array of functions and return an array. I am trying to use the for loop here.

I have the following code below:

const fnArr = [
      function firstName() {
        return this.first;
      },

      function lastName() {
        return this.last;
      },
    ];

const obj = { first: 'Nimit', last: 'Maru' };

function callAll(obj, fnArr){

  let newArray = [];

  for (let i=0; i<fnArr.length; i++){
    let eachFunc = fnArr[i]; 

    return newArray.push(eachFunc.call(obj))
  }
}

callAll(obj, fnArr)

My expected output is:

['Nimit', 'Maru']

But the output from my personal code is returning: 1

Question 1: What am I doing wrong here?

////////////////////////////////////////////////////////////////////////////////////////////////////////////

Additionally, the solution I was given is below:

const fnArr = [
          function firstName() {
            return this.first;
          },

          function lastName() {
            return this.last;
          },
        ];


const obj = { first: 'Nimit', last: 'Maru' };


const callAll = (obj, fnArr) => {
  return fnArr.map(fn => {
    return fn.call(obj);
  });
};

It produces the right answer.

Question 2: In the solution code above, why do I need the call method in "return fn.call(obj)"?

A conceptual explanation of when you need or don't need call in these types of situations would be greatly appreciated.

Upvotes: 0

Views: 100

Answers (1)

Maheer Ali
Maheer Ali

Reputation: 36564

You are returning in each loop. So after the first loop the the function ends and code doesn't execute further.

It returns 1 because push() method returns the length of the array after adding elements to it. Initally array was empty when 1 element is added it returns 1.

You don't need to necessarily use map() just push() the element(don't return). And return the newArray after loop.

const fnArr = [
      function firstName() {
        return this.first;
      },

      function lastName() {
        return this.last;
      },
    ];

const obj = { first: 'Nimit', last: 'Maru' };

function callAll(obj, fnArr){

  let newArray = [];

  for (let i=0; i<fnArr.length; i++){
    let eachFunc = fnArr[i]; 

    newArray.push(eachFunc.call(obj))
  }
  return newArray
}


console.log(callAll(obj, fnArr))

In the solution code above, why do I need the call method in "return fn.call(obj)"?

The this binding to the function depends upon how the function is called. If the function is called as the method of the object then the object will be binded to that method.

In the above code this inside your both functions will refer to window object if they are called normally. So we want this to refer the object so we use call

Why eachFunc(obj) returns [undefined, undefined]?

When you don't use call this will refer to window object. So there is not property named first and last on window object so it returns undefined

Upvotes: 2

Related Questions