Dereferencing Javascript Variables - Revisiting

Posted April 20, 2006 at 6:44 PM by Ben Nadel

Tags: Javascript / DHTML

As posted before I was having a very hard time getting dynamic onclick methods to call what I thought was a dereferenced variable. I was getting a lot of help and great suggestions on the CFTalk list, but one guy finally posted a link to:

http://calculist.blogspot.com/2005/12/gotcha-gotcha.html

This page discussed exactly the problem I was having, the reasons I was having it, and the solution. It's all about scoping of variables. The variable that I was alerting (in the dynamic onclick) was for the method (including every iteration of the FOR loop) and therefore each link pointed to it. In the solution below, the FOR loop is replaced with a repetative method call forces each variable scopes to be local.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Javascript Dynamic Variables</title>
<script type="text/javascript">

function TestClass( strName ){
this.Name = strName;
}

TestClass.prototype.AlertValue = function( anyValue ){
alert( this.Name + " is alerting: " + anyValue );
}


function Init(){
var objContentDiv = document.getElementById( "content" );
var objA = null;
var objTest = new TestClass( "Tester" );

// This runs the for loop using a LOCAL scope for each iteration.
(function loop( intI ){
var intX = intI;

if (intI < 10){

// Create new A element.
objA = document.createElement( "a" );

// Set A display properties.
objA.style.display = "block";
objA.style.backgroundColor = "#F8F8F8";
objA.style.border = "1px solid #333333";
objA.style.padding = "10px 10px 10px 10px";
objA.style.color = "#333333";
objA.style.marginBottom = "15px";

// Create text for the link.
objA.appendChild( document.createTextNode( "I should alert " + intX + " when clicked" ) );

// Set the href.
objA.setAttribute( "href", "##" );

// Set the onclick method.
objA.onclick = function(){ objTest.AlertValue( intX ) };

// Attach the A to the content.
objContentDiv.appendChild( objA );


loop(intI + 1);
}

})(0);

}


// Is the tester class available here (just testing).
alert( "objTest is of type: " + typeof(objTest));

</script>
</head>
<body onload="Init();">

<div id="content"></div>

</body>
</html>




Reader Comments

Apr 3, 2007 at 9:16 AM // reply »
2 Comments

Hey thanks for this I'd be struggling with a similar problem all morning. JavaScript really is an ugly language, this solution seems a little strange but at least it works!


Apr 3, 2007 at 9:20 AM // reply »
11,238 Comments

@Pete,

I would recommend looking into jQuery. It is an awesome Javascript framework that I have just started working with. One of the things it provides is an Each() method (this is common to many Javascript frameworks). But anyway, because the Each() method takes a function literal, it forces you to create a new local scope for each loop iteration. This, in and of itself, helps take care of many of the "referencing" issues.


Apr 3, 2007 at 9:35 AM // reply »
2 Comments

Hi Ben,

I've been meaning to check out some of the JavaScript frameworks for sometime now. I will have a look into jQuery, I am told http://mootools.net is a good light weight framework.


Apr 3, 2007 at 9:37 AM // reply »
11,238 Comments

Yeah, I have heard good things about MooTools. If you are interested in some of my jQuery tinkerings:

http://www.bennadel.com/search/jquery


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 21, 2013 at 7:46 PM
Using Plupload For Drag & Drop File Uploads In ColdFusion
No luck. At least I have uncovered the cause, URLScan 3.1. Here is what I see in the IIS log when a file is over 30mb. 2013-05-21 23:29:05 10.105.45.128 GET /plupload/assets/jquery/jquery-1.8. ... read »
May 21, 2013 at 6:12 PM
Using Plupload For Drag & Drop File Uploads In ColdFusion
Ben, I did not see you after Pete Freitag's Lockdown session at cfObjective but he said that IIS sets file size limits at 30MB by default which just happened to be the threshold for file size when ... read »
May 21, 2013 at 11:51 AM
Ask Ben: Parsing Very Large XML Documents In ColdFusion
Looking at my first ever XML document that I have to parse and put into MS SQL 2000 with CF8. I get it to list the desired Field name, many times over, and have a long list of this field name displa ... read »
May 21, 2013 at 9:25 AM
Turning Off and On Identity Column in SQL Server
you are awesome..i am lucky to get this blog between such a garbage one....Thanks, Prashant ... read »
May 20, 2013 at 4:38 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, Your confusion is well founded, since this is a very confusing features. In fact, it ONLY works if you use array notation. Meaning, that this: arrayToList( query[ "columnName" ] ) ... read »
May 20, 2013 at 4:34 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I was thinking chicken and the egg, I wouldn't have expected it to work in the valuelist going in I guess. Maybe I just need a beer, long day :) ... read »
May 20, 2013 at 4:29 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Dana, That's if you're trying to reference a specific row. In this case, we're trying to reference the entire query column as one cohesive value. So, you are correct that if you wanted to output a ... read »
May 20, 2013 at 4:24 PM
Using A Dynamic Column Name With ValueList() In ColdFusion
I thought when you used array notation to reference queries you always had to have the row or it would throw a similar error as well? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools