Highly confused with "this" , apply, call, bind , please guide!

Hi,

I was just trying to clear my concept on apply and call reading some online content and watcing some videos, when i decided to try it myself and write some code , i wrote -

function addNum(num1, num2) {
      return num1 + num2;
}
var o = {

a1: 23,
b1:26

}
addNum.apply(o);

output ----> NaN

Now i tried with out looking for solution and struggled to understand why NaN is output, as i am now applying the logic of addNum and saying take the variables from context of o…

Still i got error, then when i finally looked up i found i needed to do this …


function addNum(num1, num2) {
     return this.num + this.num2;
}

var o = {
num1: 21,
num2: 12
}

addNum.apply(o);

Now it works …

is this not highly prohibitive, i mean first of all why i need to write “this” and then why the names of variables need to be same inside object and function…

Please tell me the reason why i need to do this …

NOTE - i just read that Douglas Crockford is highly against using "this’, so can apply and bind and call be done with out “this” as well ?

Kindly help and guide in this regard …

The reason this first example did not work, is that you were not using the o object. When your code ran, num1 and num2 arguments had undefined values and undefined + undefined = NaN which is what was returned from the function.

In this second example, your function does not even need parameters num1 or num2 as you are not using them. The only way to reference the properties of o is to use “this” which tells JavaScript to use the o object as “this” based on the apply function. The exact property names must be used to get the values of the properties.

In the example you gave, if you ONLY have two numbers stored in a global object called o, then you could simply call the function and do:


because it would be overkill to write a function to do that. It could be argued you would not need a function at all for such a task when you could do the following to get sum without a function:

var sum = o.num1 + o.num2;

Now let’s look at a more practical use of your second addNum function using apply. There are probably better examples, but this is the first thing that popped into my head. I will try to post another better example later unless someone else beats me to it. In this example below, you can use apply or call and the results would be the same. What if you had an array of a million objects with each object having the structure:

{num1: value, num2: value}

Let’s say we wanted to create an array of results of adding each object’s num1 and num2 properties’ values. We could use the following to accomplish that. Note: I only have 3 objects for the sake of an example, but imagine there were a million such objects.

function addNum() {
  return this.num1 + this.num2;
}

var lotsOfObjects = [ {num1: 21, num2:12}, {num1:5, num2:10}, {num1:100, num2:200}];
var additions = [];
for (var i = 0; i < lotsOfObjects.length; i++) {
  additions.push( addNum.apply(lotsOfObjects[i]) );
}
console.log(additions); // yields [ 33, 15, 300]
1 Like

@camperextraordinaire - thank you so much for the detailed reply, my only problem is that i have been confused a lot by reading and listening to Douglas Crockford , who seems to suggest to not use “this” and that now i cannot even use call and apply with out “this” …

In jslint if i use “this” it gives warning …

Just one thing about this code


function addNum(num1, num2) {
return num1 + num2;
}

var o = {

a1: 23,
b1:26

}

addNum.apply(o);

output ----> NaN

So now if i use addNum.apply(o) …

Should JS not be able to understand i want the functionality of addNum and context of “o”. why i ask again why the need to use this if the context object is mentioned …

Also why need to have same name, if there are 2 arguments and the context has 2 numbers then do it , if more then 2 numbers take first 2 , if less then 2 give warning … if not same datatype give warning .will that not be better …

Regards

Hi @amitshrivastavafcc,

Just to piggy back off of your observation about Douglas Crockfords allergy. I believe one of the main reasons he does not like the use of this is because the keyword is context dependent and can cause confusion around which object this is referring to.

function defineThis(obj) {
  return this;
}

const object1 = { define: 'sam' };
const object2 = { define: 'adams' };
const object3 = { define: 'lover' };

object1.defineThis = defineThis //set the function on the object

const diffContext = defineThis.bind(object2); 
//bind declares a function but is not invoked.  
//Sometimes this is better than declaring the function as an 
//attribute of an object. Any ideas why this might be?

defineThis.call(object3);
//invokes a function immediately
//this is similar to ```apply``` except how you pass 
//arguments into the function. I'll let you MDN research this.

object1.defineThis(); //whats the context?
diffContext(); //whats the context?
defineThis.apply(object3); //whats the context?
defineThis(); //whats the context?

If you had a lot of code written, sometimes trying to define what this refers to will take more brainpower that could have been spent else where.

Oh…also, if you are curious about what object defineThis() as a standalone function refers to, you can type this in the chrome console to find out.

1 Like

@amitshrivastavafcc: Heres some code that could potentially become very confusing if you don’t understand the context of this. I suggest that you find out the context of the standalone defineThis() function I wrote is before attempting to answering these following questions:

defineThis(object2); //what will this return?
diffContext(object1); //what will this return?
object1.defineThis(object3); //what will this return?
1 Like