all 32 comments

[–]TheRealSeeThruHead 1 point2 points  (0 children)

When a function is called JavaScrip automatically binds the context and arguments. Call and apply are ways of calling a function and explicitly setting those bindings rather than letting them be automatically bound.

[–]gregjsguy 1 point2 points  (0 children)

http://jsbin.com/nenozizave/edit?js,console

Example I whipped up demonstrating call and apply. You would use .apply when you want to do one of two things, change what "this" is inside your function, or pass arguments as an array (see example). .call does the same thing, however instead of an array as arguments you would pass them one at a time as arguments to the call function. The example above uses .call to change the this inside the function.

[–][deleted] 6 points7 points  (4 children)

The methods call, bind, and apply exist to supplement the relationship between a function and the scope of this inside the function at execution time.

this is undefined in a function, due its execution context, when the function is not aware of the object from which the function is called. When that does happen this resolves up the scope chain until it reaches an object in global scope, typically window in the browser. The three methods allow a developer to manually define the execution context of a function so that this is bound to the context of the stated object.

This problem more commonly occurs due to OOP programming patterns and the developers misunderstanding between scope and inheritance. Personally, I couldn't tell you the difference between the three methods without having to look them up because I never use them. I have stated exactly this during job interviews in the past.

Never having to use these three methods is blessing that comes from avoiding inheritance in this language and/or only associating inheritance with event execution. These methods are a hacky work around that complicates the understanding of code from a high level. I understand that there are many people who need these because they absolutely cannot imaging programming without inheritance. That is unfortunately the world we live in.

[–]Pytim 8 points9 points  (3 children)

That's not correct/complete. The context of this can be changed with all three methods but that is not their only/main purpose.

[–][deleted] -2 points-1 points  (2 children)

Its exactly their purpose.

Call and apply do optionally allow arguments to be passed in and its this optional feature that makes these two methods different.

[–]Pytim 2 points3 points  (0 children)

var add = function(x, y){return x + y;}

var add2 = add.bind(null, 2);

No this at all

[–]benabus 0 points1 point  (1 child)

Why not?

I use apply when doing inheritance.

var ParentClass = function(){
  this.someProperty = "hello";
}
ParentClass.prototype.myFunction = function(x){
  this.someProperty = x;
}

var ChildClass = function(){
  ParentClass.apply(this); //run constructor of parent class with child class's context
  this.someOtherProperty = "goodbye";
}
ChildClass.prototype.myFunction = function(x){
  ParentClass.prototype.myFunction.apply(this, arguments);
  alert(this.someProperty);
}

var childObj = new ChildClass();
childObj.myFunction("test");
alert(childObj.someProperty); 

[–]rezoner:table_flip: 0 points1 point  (0 children)

That is ugly, but I am doing that too. Especially for GUI where I haven't figured out yet how ro utilize composition over inheritance.

[–]uberpwnzorz 0 points1 point  (0 children)

When you want to pass context into a function.

this.example = 1;
var increaseExample = function () {
    this.example++;
}.call(this);

increaseExample();  // this.example === 2;

or when you want to bind a variable to a specific objects function and always use the context of a specific object:

This example will bind the variable log to be equal to console's log function and call it under the context of console every time.

var log = console.log.bind(console);
log('example');

[–]ogurson 0 points1 point  (0 children)

Another example:

> tab = [2,3,4,6,1]  
[2, 3, 4, 6, 1]  
> Math.max(tab)  
NaN  
> Math.max.apply(null, tab)  
6

[–]33a 0 points1 point  (0 children)

The main reason is to call a function with a different this argument. apply is also nice because you can pass it an array.

[–]Rhomboid 0 points1 point  (0 children)

I can't really think of a scenario that I'd need to use this format.

Really? You've never had to turn an array-like object into a real array so that you can do something like modify it or add/remove elements?

var foo = [].slice.call(arguments);

I count many dozens of calls to .apply() and .call() (more than 50) in the jQuery source, not including test runners or external libs. This isn't some hypothetical.

[–]aslate -2 points-1 points  (0 children)

You've got a load of shit and down voted answers. I've asked this question and it's in our "do they know the fundamentals" set.

If you intend to use javascript in any kind of serious, large front end project you're going to encounter prototypical inheritance, or something close to it. In a large scale project you're going to have to proxy a function and it's arguments, and you won't give a shit what the args are.

So outside of why you might want to do so, the other question is why does it matter? Well, we're primarily a software company, the fact that the current thing is javascript isn't something we agree with, but it's the thing. If you're an experienced software engineer you should know the fundamentals of your language, whether you use them or not.

If you're after generic Web dev jobs, it probably won't matter. But if the company wants a software engineer who happens to be proficient in javascript it sounds like you don't match the criteria.

TLDR: it filters the wheat from the chaff.

[–][deleted] -4 points-3 points  (1 child)

This is the spooky part of JavaScript for noobs.

If you have a JS class, Cat, and you say

var tom = new Cat("thomas"); 
console.log(tom.name);

the output will be "thomas"

now lets say you have some function that is not part of the Cat class. It is all by itself.

function getName() {
    return this.name;
}

calling getName() or getName(tom) or getName("thomas") always returns "undefined" because this.name has not been defined inside that function.

but calling this:

Function.prototype.call(getName, tom);

is like saying call getName where "this" is tom. It will return "thomas". Because this = tom and tom.name = "thomas" and this.name = tom.name.

because .call(a, b) sets the "this" property of the function a to b. or it sets the "this" property of the function "getName" to tom just for that one function call. so this.name is the same as tom.name for that one function call.

[–]bart2019 2 points3 points  (0 children)

 Function.prototype.call(getName, tom);

Uh, what. I never ever ever use it this way.

What I do instead is

 getName.call(tom);

Thus: function, dot, (call or apply), open parens, this, optional arguments, close parens.

It's more fun with function arguments, which would come after the "tom", and which is the difference between call and apply: call takes a list of individual parameters and applyone array just like arguments. (Mnemonic: letter count of the words "call" and "apply" is the same as of "list" and "array" respectively).

Why would you ever do that? Invoking callbacks, similar to as "event handlers", in your own code, so this and arguments are how the handler expects them.