0

I am trying to understand the bind method and I have written the below code :

//
//Window Context
function Hello(d) {
    //Always this reffers to calling context
    console.log(d);
}

Hello("ABC");

function Student(sname) {
    this.name_n = sname;
    this.hello = Hello;
    this.printAfter2Seconds = printAfter2Seconds.bind(this);
    this.print = function() {
        console.log(`Student Name: ${this.name_n}`);
    }
}

printAfter2Seconds = function() {
    console.log(`Before Set TimeOut - ${this.name_n}`);
    //let that = this;
    setTimeout(function() {
        //console.log(this);
        console.log(`After Set TimeOut - ${this.name_n}`);
    },2000);
}

function Department(dname) {
    this.name_n = dname;
    this.hello = Hello;
    this.printAfter2Seconds = printAfter2Seconds.bind(this);
}

let s = new Student("ABC");
s.hello(s.name_n);
s.printAfter2Seconds();

let d = new Department("IT");
d.hello(d.name);
d.printAfter2Seconds();

//

If I comment the setTimeout line and the line ending setTimeout like below :

//setTimeout(function() {
            //console.log(this);
            console.log(`After Set TimeOut - ${this.name_n}`);
  //      },2000);

I am getting the expected output ABC and IT. But If I include setTimeout I am getting undefined both time. So I am guessing some where I need to invoke bind again. This may not be a trivial example that you use everyday just trying to understand bind.

So I need to understand how to bind the this context of the function inside setTimeout or that is even possible.

Thanks in Advance.

Abhilash D K
  • 741
  • 1
  • 14
  • 31
  • If going down the `.bind` route, you need to `.bind` the function you pass into `setTimeout` (or one of the other solutions shown by the linked questions' answers), since that's a second opportunity for `this` to change. But in modern JavaScript, you'd use [an arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) instead. – T.J. Crowder Jul 06 '18 at 12:30
  • you would append it to the closing bracket of your setTimeout, like so: }.bind(this), but like @T.J.Crowder already mentioned, the arrow-function would be better. – evayly Jul 06 '18 at 12:31
  • @Durga there is no problem with let that = this; But I am under the assumption that bind solves let that = this; statement. Is that correct? – Abhilash D K Jul 06 '18 at 12:31
  • @T.J.Crowder thanks. Yes I do know arrow functions. But I am trying to understand the problem the arrow function solves. So was trying to understand bind. – Abhilash D K Jul 06 '18 at 12:33
  • @evayly Yes your solution worked. Thank you :) – Abhilash D K Jul 06 '18 at 12:34
  • AbhilashDK - The linked questions' answers should help with that. But @Durga's now-deleted suggestion of `let that = this;` and then using `that` in the callback is useful to explain arrow functions. If you did that, it would work because the function you're passing `setTimeout` *closes over* `that`. Arrow functions work **exactly** the same way: They *close over* `this` (whereas all other kinds of functions have their own `this` that's set by how they're called). Happy coding! – T.J. Crowder Jul 06 '18 at 12:38
  • @T.J.Crowder Thank you very much for the links and the explanation. So the arrow functions are kind of a syntactic sugar for .bind(this). Is my understanding correct? – Abhilash D K Jul 06 '18 at 12:41
  • @AbhilashDK - *Sort of*, but three differences (two big ones): 1. You can use things other than `this` with `bind` so it's not quite the same thing. 2. Arrow functions also close over things `bind` doesn't control (`super` and `arguments`). 3. Arrow functions are lighter-weight than traditional functions: They don't have a `prototype` property with associated object (whereas all other functions do in case they're used as constructors [e.g., via `new`]), and they cannot be called as constructors. – T.J. Crowder Jul 06 '18 at 12:46
  • 1
    @T.J.Crowder Thank you very much for mentioning the differences :) – Abhilash D K Jul 06 '18 at 12:48

0 Answers0