0

In JavaScript, we can call a function in two ways:

function f(message) { ... }
f.call(this, "test");

or just:

f("test")

Except that we can specify the scope in the first case, is there any other advantage to using this syntax over the other one?

Kijewski
  • 25,517
  • 12
  • 101
  • 143
Victor
  • 16,609
  • 71
  • 229
  • 409
  • I imagine you could use the `call` form to execute a function member of an object with `this` bound to another object, while still within the closure of the first object. There might be some use but I've never done that. – OregonTrail Mar 24 '13 at 22:29
  • `call` isn't even a keyword in JavaScript. – Derek 朕會功夫 Mar 24 '13 at 22:39

3 Answers3

4

You can pass a this object as you like/need. E.g.

[].slice.call("abcdef", 2) === ['c', 'd', 'e', 'f'];

or

var x = {hasOwnProperty:function() { return false; }, key:42};
x.hasOwnProperty('key'); // == false
{}.hasOwnProperty.call(x, 'key'); // true

You should take notice that call is not a keyword, but a method of Function.prototype.

Read:

Kijewski
  • 25,517
  • 12
  • 101
  • 143
  • 1
    +1, but note that in ES5 strict mode, `this` can be set to any value (including `null` and undefined), not just an object. – RobG Mar 24 '13 at 22:43
3

Except that we can specify the scope in the first case

You can't "specify scope". Scope is set by how code is written, you can't dynamically change it other than to a limited extent using with. A function's this keyword has nothing to do with scope, it's always resolved as a local variable in the current execution context.

RobG
  • 142,382
  • 31
  • 172
  • 209
1

You can also use call (and apply) for partial function application, which is when you create a function that calls another function with some preset arguments. For example:

// Basic add function
function add(a, b) {
    return a + b;
}

// Function to create new adders with a preset 'a' argument
function createAdder(a) {
    return function(b) {
        return add.call(null, a, b);
    }
}

// Let's create a function that always adds five to what's passed in
var addFive = createAdder(5);

// Now let's test it
addFive(6); // 11 - it works!
Community
  • 1
  • 1
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • In recent browsers (since IE9) you would prefer `addFive = add.bind(null, 5)`. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind – Kijewski Mar 27 '13 at 00:57
  • 1
    True, but when you want to partially apply a variable number of arguments, you still need to use `apply` (because it takes an array of arguments). – bfavaretto Mar 27 '13 at 01:45