...

View Full Version : Problem with passing object as argument



qwertyuiop
01-05-2012, 06:16 AM
function $(x) {
return document.getElementById(x);
}

function test(x) {
alert(x.id);
}

function init() {
var o = {};

o.id = "a";
$("one").addEventListener("click", function () {test(o);});

o.id = "b";
$("two").addEventListener("click", function () {test(o);});

o.id = "c";
$("three").addEventListener("click", function () {test(o);});
}

window.onload = init;

I have some code similar to this. When the HTML elements with id's "one", "two", or "three" are clicked, they all alert "c", but I want them to alert the respective values (a, b, and c).

How can I pass the object by value and not by reference? I guess in this simple example you would just define two more objects, but my code is actually within a for-loop. The object properties are changed each iteration (ideally each iteration creates a new object) and then passed to the function.

Logic Ali
01-05-2012, 06:52 AM
Your object 'o' persists in the closure, so its last-assigned value is always read.
One way could be to do this:

function init()
{
var t = [ 'a', 'b', 'c' ];

$("one").addEventListener("click", function () {test( t[0] );});


$("two").addEventListener("click", function () {test( t[1] );});


$("three").addEventListener("click", function () {test( t[2] );});
}

qwertyuiop
01-05-2012, 07:25 AM
Thanks Logic Ali. I guess I simplified my example a bit too much though, or wasn't clear enough. The function test takes an object as a parameter, not just a simple string.

Old Pedant
01-05-2012, 07:38 AM
You can't do it.

You are under the mistaken impression that there are three (or four) objects in use.

NOT TRUE.

JavaScript *ALWAYS* passed object by REFERENCE. You can never actually hold an object in a variable.

Now, if you REDEFINED the object between adding each listener, you could do it with a closure.


<html>
<head>
<script>
function $(x) {
return document.getElementById(x);
}

function test(x) {
alert(x.id);
}

function addClickTo( towhat, withwhat )
{
towhat.addEventListener("click", function( ) { test(withwhat); } );
}

function init() {
var o = { id: "a" };
addClickTo( $("one"), o );


o = { id: "b" };
addClickTo( $("two"), o );

o = { id: "c" };
addClickTo( $("three"), o );

}

window.onload = init;
</script>
</head>
<body>
<input type="button" id="one" value="one"/>
<input type="button" id="two" value="two"/>
<input type="button" id="three" value="three"/>
</body>
</html>

Old Pedant
01-05-2012, 07:43 AM
I guess the other way to do it would be to clone the object as part of the closure function:


<script>
function $(x) {
return document.getElementById(x);
}

function test(x) {
alert(x.id);
}

function addClickTo( towhat, withwhat )
{
var usethis = { }
/* write code here to clone withwhat into usethis */
towhat.addEventListener("click", function( ) { test(usethis); } );
}

function init() {
var o = { };
o.id = "a";
addClickTo( $("one"), o );

o.id = "b";
addClickTo( $("two"), o );

o.id = "c";
addClickTo( $("three"), o );

}

window.onload = init;
</script>



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum