You-dont-know-js: "this & object prototypes": Chapter 2 'Implicitly Lost' question

Created on 27 Apr 2016  路  2Comments  路  Source: getify/You-Dont-Know-JS

In chapter 2, there is a part about 'implicitly lost', i use the code of chapter 1 with some modification:

function foo(num) {
    console.log( "foo: " + num );
    // keep track of how many times `foo` is called
    this.count++;
}

var fooObj = {
  count: 0,
  foo:foo
}

var baz = fooObj.foo;

for (var i=0; i<10; i++) {
    if (i > 5) {
        baz( i );
    }
}
console.log( foo.count );

Of course it is a example of 'implicitly lost'. I try to fix this with call/apply "like this in jsbin":

function foo(num) {
    console.log( "foo: " + num );
    this.count++;
}

var fooObj = {
  count: 0
}

for (let i=0; i<10; i++) {
    if (i > 5) {
      setTimeout(foo.call(fooObj, i), 100);  
    }
}

// how many times was `foo` called?
console.log( fooObj.count );

here is the answer:

"foo: 6"
"foo: 7"
"foo: 8"
"foo: 9"
4

yes, I get the right answer, but when I review the code, actually, I find I can not get the right answer!

Because each setTImeout's callback will execute after 100ms, that is to say, the console.log( fooObj.count ) will execute before the callback! I should get 0 instead of 4!

Why is that?

Most helpful comment

The reason is that foo.call(fooObj, i) is invoked immediately. Try using bind instead: foo.bind(fooObj, i). Alternatively you can wrap the call in a function to have it executed later: function () { foo.call(fooObj, i) }.

Btw, a neat thing about bind: If you want to emulate call using bind, just do foo.bind(fooObj, i)().

All 2 comments

The reason is that foo.call(fooObj, i) is invoked immediately. Try using bind instead: foo.bind(fooObj, i). Alternatively you can wrap the call in a function to have it executed later: function () { foo.call(fooObj, i) }.

Btw, a neat thing about bind: If you want to emulate call using bind, just do foo.bind(fooObj, i)().

@EirikBirkeland nice. It is my mistake. thanks for your help :+1:

Was this page helpful?
0 / 5 - 0 ratings