Scope and Binding in Javascript

From Zanecorpwiki

Jump to: navigation, search

Work in progress. None of the code has been tested yet.

Binding in Javascript happens at the last possible moment and is purely symbol based.

Example 1:

pre var link = document.createElement('a'); link.appendChild(document.createTextNode('example')); link.href = '#'; link.onchange = function() {

  doSomething(foo);

} block.appendChild(a);

foo = '12'; function doSomething() { alert(foo); return false; } /pre

'doSomething' and 'foo' are referenced before they are defined, but that's okay. In the program flow, they are not evaluated until the link is clicked, by which time both will have been defined.

Example 2:

pre doSomething(foo); foo = '12'; function doSomething() { alert(foo); return false; } /pre

On the other hand, this will fail because doSomething is undefined when the first line of code tries to execute it. Moving the function definition above the call would give an alert with 'null'.

Example 3:

Now, for something a little more subtle:

pre for (var i = 1; i = 4; i++) {

 var link = document.createElement('a');
 link.appendChild(document.createTextNode('Link #' + i));
 link.href = '#';
 link.onclick = function() { alert(I'm link # + i); return false; };
 block.appendChild(link);

} /pre

This will add 4 links to the block. They will read Link #1, Link #2, etc. Clicking on any link will produce an alert I'm link #4. To understand this, remember our first rule: binding happens at the last possible moment. In the first use of i, in the label creation, the binding happens within the loop, so i is during the first evaluation, 2 in the second, etc. In the second use (in the alert function), evaluation and binding does not occur till the onclick function is evaluated. At this point, i == 4! To fix this, we have to force the binding of i:

pre function createAlertFunction(i) {

 return function() { alert(I'm link # + i); return false; };

}

for (var i = 1; i = 4; i++) {

 var link = document.createElement('a');
 link.appendChild(document.createTextNode('Link #' + i));
 link.href = '#';
 link.onclick = createAlertFunction(i);
 block.appendChild(link);

} /pre

Now i will be found when createAlertFunction is called, producing four anonymous functions with their own correctly bound values for i.

Personal tools