0

I have a question relative to this code. It should (and it does) display a list of items, where you can add and remove entries by clicking on the plus and minus.

<html><head><script src="http://www.google.com/jsapi"></script>
<script>
google.load("jquery", "1.3.2");
app={};
app.attachList = function() { 
 return {
 _current_id : 0,
 addFilterAfter : function(after_entry_id) {
 that = this;
 new_id = this._newId();
 jQuery("#entry_"+after_entry_id).after("<li id=\"entry_"
 +new_id+"\"><a href=\"javascript:void(0);\" id=\"entry_"
 +new_id+"_add\">(+)</a><a href=\"javascript:void(0);\">(-)</a> hello "
 +new_id+"</li>"); 
 jQuery("#entry_"+new_id+"_add")
 .bind("click", function() { 
 that.addFilterAfter(new_id); 
 } 
 );
 }, 
 show : function() {
 that = this;
 new_id = this._newId();
 jQuery("#list").children().remove();
 jQuery("#list").append("<li id=\"entry_"
 +new_id+"\"><a href=\"javascript:void(0);\" id=\"entry_"
 +new_id+"_add\">(+)</a> hello </li>");
 jQuery("#entry_"+new_id+"_add")
 .bind("click", function() { 
 alert(new_id); // HERE
 that.addFilterAfter(new_id); 
 }
 );
 }, 
 _newId : function() {
 this._current_id++;
 return this._current_id;
 },
 };
} 
app.main = function() { l = app.attachList(); l.show(); }
google.setOnLoadCallback(function() { jQuery.noConflict(); jQuery(document).ready(app.main); }); 
</script>
<ul id="list" /></ul>
</head>
</html>

My question is relative to what happens at the line marked HERE. Ideally, if I click the first item +, I would expect this code to continue adding just below the first item. This does not happen. It continues incrementing the new_id (as you can see from the alert) instead of keeping the original new_id it was granted.

Now, I have a suspect about what's going on, mostly involving the closure nature of javascript, but I want to hear it explained from someone more skilled.

As a side note, if I partition the logic for binding the event in a separate method, it works as expected... from this my suspect.

asked Dec 28, 2009 at 5:24

1 Answer 1

4

The problem that is causing this behavior in your code is that you're missing the var statement when you assign a value to new_id.

In JavaScript when you make an assignment to an undeclared identifier (an identifier not reachable in the scope chain), it becomes global (window.new_id is created) and that's why it keeps incrementing.

answered Dec 28, 2009 at 5:39
Sign up to request clarification or add additional context in comments.

2 Comments

thank you. I thought new_id was kept as a reference to this._current_id within the function. Instead, I was just referring to a damn global :). But then I don't understand why, when I isolated the bind() call in a different method routine, it worked correctly.
However, lesson learned. I won't forget var anymore in my javascript life.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.