Gyanesh Gouraw
Gyanesh Gouraw

Reputation: 2021

Understanding callbacks and related lexical scoping

I am trying to understand callbacks via setTimeout function. I have two sets of code :

for (var i = 1; i <= 10; i++) {
        (function(callback,i){
          setTimeout(function(){
            callback(i)
          }, 0);
         })(function(val){console.log(val)},i);

It works fine printing 1,2,3,.... 10

But when i am trying to abstract setTimeout's callback function as :

for (var i = 1; i <= 10; i++) {
        (function(callback,i){
          setTimeout(func, 0);
         })(function(val){console.log(val)},i);
        }
function func(){
    callback(i)
  }

It gives me error stating

Uncaught ReferenceError: callback is not defined

I know there is some issue with lexical scoping of declaration of that func function. But not able to comprehend the reason. Please do help me understand this.

Upvotes: 1

Views: 115

Answers (3)

RIYAJ KHAN
RIYAJ KHAN

Reputation: 15290

In func you don't have reference to callback that you declared in your IIFE.So,it start looking in current scope which is your func scope.then it try to find in global scope,it also not defined there.Finally it throws an error

You need to pass the refarence to this callback parateter refering the function to get rid of this error.

for (var i = 1; i <= 10; i++) {
        (function(callback,i){
          setTimeout(func.bind(null,callback,i), 0);
         })(function(val){console.log(val)},i);
        }
function func(callback,i){
    callback(i)
  }

Upvotes: 1

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67217

It is throwing reference error because, the function func it has a scope where there is no declaration for callback. You can fix it by passing the callback as a parameter to func.

for (var i = 1; i <= 10; i++) {
  (function(callback, i) {
    setTimeout(func, 0, callback.bind(null, i)); //Pass the callback here as a parameter to func. 
                                   //(setTimeout can pass its >2 parameter as 
                                   //its callback parameter)
  })(function(val) {
    console.log(val)
  }, i);
}

function func(callback) { //receive the callback here and use it.
  callback();
}

Upvotes: 2

guest271314
guest271314

Reputation: 1

callback is not defined within func . You can pass func as parameter to IIFE, use Function.prototype.bind() to pass i to callback : func

for (var i = 1; i <= 10; i++) {
  (function(callback, i) {
    setTimeout(callback.bind(null, i), 0);
  })(func, i);
}

function func(val) {
  console.log(val)
}

Upvotes: 2

Related Questions