Question

Please look at the code below and explain: what am I doing wrong?

    function doStuff(a, b){
      return a + b + 1 ;
    }

    var myContext = {
       c: 1, 
       d: 3
    };

// myContext = this (result => 5)
    doStuff.call(myContext,myContext.c,myContext.d)

// ... so why doesn't the below work? (result => NaN)
    doStuff.call(myContext,this.c,this.d)

// To make the above work, i must replace "this" with "myContext" (result => 5)...
    doStuff.call(myContext,myContext.c,myContext.d)

// ...which is no different to... 
    doStuff(myContext.c,myContext.d)

// ...so what was the point of call() method?

Am I being thick?

Was it helpful?

Solution

The main point of call is to set the value of this within the function. Since your doStuff doesn't use this within the function, using call with it is pointless.

Here's an example where it matters:

function doStuff(a, b) {
    return this.sum(a, b);
}
var obj = {
    sum: function(a, b) {
        return a + b;
    }
};
console.log(doStuff.call(obj, 3, 4)); // 7, because `obj` has a `sum` property
console.log(doStuff(3, 4));           // Fails with an error that `this.sum` is not a function

so why doesn't the below work? (result => NaN)

doStuff.call(myContext,this.c,this.d)

Because this.c is evaluated before the call to doStuff, using whatever the current this value is. How you're probably calling that code, this is (in loose mode) the global object (the window object, on browsers), which probably doesn't have a c or d property. (In strict mode, again making assumptions about how you're calling that, you'd get an exception, because this is undefined and you can't retrieve properties from undefined.)

OTHER TIPS


.call and .apply are Function methods that 'manipulate' what this means inside a function.

doStuff.call(myContext, myContext.c, myContext.d): here you've set myContext as context for doStuff function and you may refer to it inside by using this, and you've passed two arguments to it: myContext.c, myContext.d, it works as you've intended...


doStuff.call(myContext, this.c, this.d): again myContext is context for doStuff() but you've passed .c and .d properties of what this points to in context in which it appears (global object, window) in your case. So doStuff's context is myContext, and parameters are 2 undefineds, because this === window in context where you are calling the function, and you are passing .c and .d properties of global into the function. you are actually getting this: return undefined + undefined + 1; (NaN)


if you redefine 'doStuff' like this:

function doStuff () {

  return this.a + this.b + 1;

  // here it looks whatever this is set to 
  // by `.call()` or `.apply()` methods

}

and call it like this:

var sum = doStuff.call(myContext);

// notice that using `.call` here 
// means that 'myContext' is manualy set 
// as `this` value inside the function above
// and is refered to by dynamic variable 'this'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top