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?
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:
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)().