0

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.

1
  • 2
    return stops the execution of a function, hence return newArray.push(eachFunc.call(obj)) is wrong on it's own because it stops the loop after the first iteration. Furthermore you're returning what-ever .push() returns - which is the new length of the modified array; Commented Jun 2, 2019 at 15:25

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

4 Comments

ah! you are right, thank you; My follow-up question is why do I need the .call() method? eachFunc(obj) returns [undefined, undefined]
"You don't need to necessarily use map()..." - Yes, but why not use something that has been implemented for exactly this purpose...
@PineNuts0 Because you're using this in your functions
@Andreas I said necessarily. New users doesnot understand higher order functions and map() so that's why I showed the other solution. Its necessary for programmer to know how the he can answer the question with using simple features. If a person don't understand return and simple for loop then its not useful to answer him using advanced features.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.