0

In one of the blogs I've learnt that .bind() will just hard bind the passed object to 'this' where as .call() will execute that function in addition. However, assigning the .call() to other variable will achieve the same purpose. I'm trying to understand why .bind() is introduced or am i missing something? Following is the code that proves what i'm saying above:

function foo () {
    console.log( this.a );
}

let obj = {
    a: 2,
    foo: foo
};

let a = 'oops! global';

let foocall = foo.call (obj);
let foobind = foo.bind (obj);

foo.call (obj);

setTimeout ( foocall , 100);
setTimeout ( foo , 100);

output:

[xyz: ~/sandboxes/js]$ node --use-strict binding.js 2 2 2

1
  • 1
    The output of your quoted code is not what you've shown (e.g., not 2 shown three times). Commented Oct 25, 2015 at 13:00

1 Answer 1

5

However, assigning the .call() to other variable will achieve the same purpose.

No. I don't know where you've read that, but it's completely wrong. Assigning the result of call assigns the result of calling the function. It does not do what bind does.

In your code, foocall is undefined. Why? Because you've called foo and assigned its return value to foocall. Since foo never uses return with a value, the result of calling foo is undefined.

call calls the function (the clue is in the name :-) ), setting the value this will have during the call.

bind does not call the function, it returns a new function that, when called, will call the original with this set to a specific value (and optionally with initial arguments, if you supply those in addition to the this value when calling bind).

Those links are to MDN (I used to link to the spec, back when the spec was intelligible to normal people), which has further explanations and examples. (Thank you for the reminder, Oskar!)

Here's a corrected example:

function foo(label) {
  snippet.log(label + ", " + this.a);
}

var obj = {
  a: 2,
  foo: foo
};

var a = 'oops! global';

// CALLS `foo`, setting `this` during the call to `obj`.
// Result: Outputs "call1, 2" to the console.
var foocall = foo.call(obj, "call1");

// Since `foo` doesn't return anything, `foocall` is `undefined`
snippet.log("foocall's value: " + foocall);

// Calls `foo`, just like we did earlier
// Result: Outputs "call2, 2" to the console.
foo.call(obj, "call2");

// DOES NOT call `foo`. Just creates a new function that,
// when called, will call `foo` with `this` set to `obj`.
var foobind = foo.bind(obj, "bound");

// Calls the bound version of `foo` after 100ms
// Result: "bound, 2" 100ms later
setTimeout(foobind, 100);

// Calls `foo` after 100ms. Since we're in loose mode,
// `foo` will get called with `this` set to the global object.
// Result: "undefined, oops! global" because we haven't passed
// a value for the `label` argument, and `this` is the global object
setTimeout(foo, 100);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

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

1 Comment

Thanks for the explanation. That was very clear. Well, you may need to edit line number 20, replace call1 with call2. It's a typo during copy/paste.

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.