-1
getTodos(function(){
    console.log(todos)
});


function getTodos(callback) {
    setTimeout(function() {
        const todos = [{title:"Walk the dog"},{title:"Feed the cat"}];
        callback();
    },1000);
};

I thought the callback function when executed after 1 sec will be able to see the todo const. But the interpreter tells me todos is not defined

Am i missing something here?

To add more knowledge that i learnt from a fellow programmer here: "Parent scope is not where its called but where its defined"

var todos = [{title:"Curb the dog"},{title:"Tickle the cat"}]
var cb = function(){
    console.log(todos);
}
getTodos(cb);


function getTodos(callback) {
    setTimeout(function() {
        const todos = [{title:"Walk the dog"},{title:"Feed the cat"}];
        callback();
    },1000);
};
laiboonh
  • 1,377
  • 1
  • 9
  • 19
  • See [What is the scope of variables in JavaScript?](http://stackoverflow.com/q/500431/1529630) – Oriol May 07 '16 at 00:57
  • 1
    JavaScript has [lexical scope](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping). Your example would probably work if JavaScript had *dynamic scope*, but it doesn't (and I believe very few languages do). – Felix Kling May 07 '16 at 01:07

1 Answers1

4

Of course it is undefined because

function(){
    console.log(todos)
}

is outside of the scope of the getTodos function.

To fix it, you can pass todos into the callback function:

getTodos(function(todos){
    console.log(todos)
});

function getTodos(callback) {
    setTimeout(function() {
        var todos = [{title:"Walk the dog"},{title:"Feed the cat"}];
        callback(todos);
    }, 1000);
}

Protip: const todos doesn't mean the value in todos is constant and cannot be changed.

Quick check:

const list = ["Apple", "Banana"];
list[2] = "Coffee Beans";
list;                     // ["Apple", "Banana", "Coffee Beans"]

list.splice(0,1);
list;                     // ["Banana", "Coffee Beans"]

list = "something else";  // Uncaught TypeError

In other words, todos is a constant reference but that's probably not what you thought it was.

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
  • Thanks for sharing your knowledge. I sort of assumed that console.log(todos) when unable to find todos in the functional scope will look for it in the parent scope – laiboonh May 07 '16 at 01:04
  • Ditto. I've never used callbacks quite this way before. Thanks for sharing the technique. – zipzit May 07 '16 at 01:05
  • 3
    @user1677501: It does. The parent scope is not where the function is *called* but where it is *defined*, because of **lexical scope**. – Felix Kling May 07 '16 at 01:05