1

I have an eventhandler and functions used to add items to a list and remove items from a list. My first function (handler) is works with the btn elements being stored in a local variable to the functions. If I try to do the same with the remove button I get a reference error in the dev tools. If I move the variable that is getting the remove button out of the function and make it global then it works. Why does one function work with the variable for the button set in the function, and the other function doesn't. Here's my code. The variables in question are commented

var handler = function(event){

  //this btn variable does work when declared inside handler function

  var btn = document.getElementById('btn');
  var input = document.getElementById('input').value;
  var item = document.createElement('li');
  var list = document.getElementById('list');
  var x = document.createElement('button');
  item.innerHTML = input;
  list.appendChild(item);
  item.appendChild(x);
};
//This dlt variable doesn't work if declared in function remove

var dlt = document.getElementById('delete');

var remove = function(event){
  var list = document.getElementById('list');
  var item = document.querySelector('li');
  list.removeChild(item);
};

btn.addEventListener('click', handler);
dlt.addEventListener('click', remove);
mikeLspohn
  • 495
  • 1
  • 8
  • 21

2 Answers2

2

Referring to btn only works by chance.

It doesn't refer to the variable that you declared inside the handler function, it refers to the global variable btn which was automatically created because you have an element with ID btn. See Do DOM tree elements with ids become global variables? for more info.

You can easily test this by changing the variable name to var button = document.getElementById('btn'); and button.addEventListener('click', handler);. You will notice that this doesn't work either.

JavaScript has function scope, so every variable that is declared (var foo;) inside a function can't be accessed from outside the function.

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Thank you that clears it up. I know about function scope and haven't had any problems with it until now this just kind of threw me. With these two handlers and all the variable what would be best practice for me to do to keep the global namespace as clear as possible. Should I pull the variables out of the functions and wrap the whole code in an iife. Or is that not good practice for this scenario. – mikeLspohn Oct 13 '14 at 19:21
  • It's definitely good to reduce the number of necessary global variables. – Felix Kling Oct 13 '14 at 19:22
1

here a little example how scopes work in JS:

var i = "hello"; // Defined global var to "hello"

function test(){ // Define Function to test scope
    var i = "world"; // Function internal var
    console.log("1: "+i); // will always give "world" back
}

test();

console.log("2: "+i); // Will give "hello" back

Let's start the code...

You will see in you JS Console:

>1: world
>2: hello

However if you change one simple thing: Remove the "var" in front of i

var i = "hello"; // Defined global var to "hello"

function test(){ // Define Function to test scope
    i = "world"; // This will overwrite the global var with "world"
    console.log("1: "+i); // will also give "world" back
}

test();

console.log("2: "+i); // Will give "world" back

Let's start the code...

You will see in you JS Console:

>1: world
>2: world

Hope it helped you ;)

Best regards

Dustin

Dustin Hoffner
  • 2,025
  • 1
  • 14
  • 15
  • Thank you. I understand scope for the most part that's why I didn't quite understand why one function has the variable declared locally and worked, and the other function had to declare it's variable global to work. Thank you for the advice though! – mikeLspohn Oct 13 '14 at 19:22