Page 1 of 1
JavaScript - Weird Array assignment behavior
Posted: Tue Aug 09, 2005 9:37 pm
by Ambush Commander
Hello, I'm learning JavaScript, and I'm getting really hung up on this:
Code: Select all
i = new Array();
i[0] = 'asdf';
i[1] = 'pork';
j = i;
k = i;
j.splice(0,1);
alert(i);
Theoretically, i should still be an Array with asdf and pork, but it's just pork now. Can someone explain this behavior to me as in PHP, this would never ever happen unless I passed a reference.
Posted: Tue Aug 09, 2005 9:41 pm
by feyd
you hit it on the nose.. the array is being passed around as a reference. Javascript is mostly based off of C and C++, therefore an array's name is merely a pointer (reference) to the data. All objects in Javascript are passed by reference. Arrays in Javascript are objects.
Posted: Tue Aug 09, 2005 9:42 pm
by Ambush Commander
So then how do I get a "copy" of the array?
Posted: Tue Aug 09, 2005 10:34 pm
by feyd
create it:
Code: Select all
<html>
<head>
<title>Feyd's wacky world of tests</title>
<script language="Javascript">
function displayIt(obj)
{
var where = 'input';
if(arguments.length > 1)
where = arguments[1];
var buf = new Array();
if(typeof(obj) == 'object')
{
for(var i in obj)
{
buf[buf.length] = 'object['+i+'] = ' + obj[i];
}
buf = buf.join('\n');
}
else
{
buf = obj;
}
document.getElementById(where).innerHTML = '<pre>'+buf+'</pre>';
}
function clone(obj)
{
var newb;
var con = obj.constructor.toString();
var type = con.replace(/^\s*function\s*([a-z_][a-z0-9_]*)\(.*/ig,'$1');
type = type.split('\n');
type = type[0];
eval('var clone = new '+type+'();');
for(var i in obj)
{
clone[i] = obj[i];
}
return clone;
}
function testIt()
{
var arr = new Array('asdf','ASDF','FDAS','fdas','1234','4321');
var ar2 = clone(arr);
arr.shift();
arr.shift();
displayIt(arr);
displayIt(ar2,'output');
}
</script>
<style>
div#input,
div#output
{
border: 1px solid gray;
background: whitesmoke;
border-top: 1px solid red;
margin-bottom: 10px;
padding: 2px 4px;
width: 250px;
}
</style>
</head>
<body>
<a href="javascript:testIt();">Test it!</a>
<div>
Array 1:<div id="input"></div>
Array 2:<div id="output"></div>
</div>
</body>
</html>
tested in Firefox 1.0.6 and IE 6.0.2900 SP2
Posted: Wed Aug 10, 2005 12:04 pm
by Ambush Commander
Wow! That's very complicated.
If I'm not mistaken, the first function is a convenience function to let you output the contents of an object in a fashion that is more descriptive than [object Object].
Clone() is our copier function. Hmm... it appears that taking the function "constructor" and translating it into a string like "function Array(arg) {etc.". and grab the "Array". Then you create a new object on what you based the function on, then you loop through the old Object and assign those values to the new object.
Speculation If the array contained objects, I bet you'd have references! Possible solution: make the function recursive. [/endspeculation] Then you return the cloned object.
Wow. That's pretty spiffy. I suppose that if you pass the function a blank copy of the new object, that would eliminate the fancy regexps and the eval.
Lots of tricks hmm... well I guess I have to learn more.
It occured to me that if I create a constructor that initializes the objects with the values I want it to have, all I have to do is:
Code: Select all
i = new ArrayWithValues();
j = new ArrayWithValues();
And they'll be copies, which works for my instance.