0

I'm just trying out function.apply() in javascript, I'm having trouble understanding how it parses the array parameter we pass in. For example,

var update = function(name, profession){
    this.name = name;
    this.profession = profession;
}

var p1 = {
    name : "bond", 
    profession : "actor"
}

console.log(p1.name, p1.profession);  //outputs bond actor

Now lets change p1's properties using apply() method

update.apply(p1, ["john", "developer"]);

1st argument is value for this pointer, and 2nd argument is an array

console.log(p1.name, p1.profession);  //outputs john developer

The function update() takes in two parameters name and profession, but I'm only passing in one array parameter ["john", "developer"] to it through apply() method. I do not understand how my update() method is correctly capturing the properties from the array that is passed in and updating each property accordingly.

Thank you!

3
  • 1
    Its works similar to ES6 spread operator. The first argument is your context or this as you said in its entirety. The second array will be expanded so that each argument in the array becomes a separate function parameter when the function is called. Commented Apr 11, 2016 at 21:36
  • 1
    Why would it matter how apply does that? It's exactly what apply was meant to do, and you seem to know that it does it, so what's the problem? Commented Apr 11, 2016 at 21:38
  • @Bergi Judging by the example code i think there is confusion that the OP thinks the two are linked in some way. They are passing in context and arguments with apply, but then in the update method setting the context properties as though it was some form of constructor. Both approaches are not needed at the same time. They have the same affect either way. Commented Apr 11, 2016 at 21:43

1 Answer 1

3

apply works by spreading out the array and passing each element of that array as a different parameter. This is all determined by the order in which they appear in the array.

Example:

function printThings(pre, a, b, c) {
  var el = document.querySelector('pre'); // Put the text into an element
  el.innerHTML += pre + '> 1: ' + a + '\n';
  el.innerHTML += pre + '> 2: ' + b + '\n';
  el.innerHTML += pre + '> 3: ' + c + '\n\n';
}

// Calling it normally
printThings('Normal', 'A', 'B', 'C');

// Call using apply
// Notice how the array is in the same order as when we called it normally
printThings.apply(null, ['Apply (1)', 'A', 'B', 'C']);

// Now we'll rearrange the arguments
printThings.apply(null, ['Apply (2)', 'C', 'A', 'B']);
<pre></pre>

It's also worth mentioning the first argument passed to apply. In the previous examples, I was passing in null since I'm not using this inside of the function at all. But what if I was? Then I can set this to the value passed as the first argument.

function printThings(pre) {
  var el = document.querySelector('pre');
  // Here, we expect "this" to be an object with a, b, and c properties
  el.innerHTML += pre + '> A: ' + this.a + '\n';
  el.innerHTML += pre + '> B: ' + this.b + '\n';
  el.innerHTML += pre + '> C: ' + this.c + '\n\n';
}

// Passing in null defaults to using the global context
printThings.apply(null, ['Global']);

// Notice how they're all undefined since there are no a, b, or c properties on the global scope

// But now we'll pass it an object with some values
printThings.apply({
  a: 'A',
  b: 'B',
  c: 'C'
}, ['Matching Values']);

// And just to drill the point home, here's an object with the right properties but different values
printThings.apply({
  a: 'Here',
  b: 'We',
  c: 'Go'
}, ['Different']);
<pre></pre>

The exact nitty-gritty details of how it works depends on the JS engine you're running it in.

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

Comments

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.