Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery object passed as argument to function is value copy not reference?

My understanding: in Javascript objects and arrays get passed as references not values for function arguments. A jQuery group is an object and hence should be passed as reference.

However I'm finding in the test script below that something strange is going on; the jQuery group is behaving like a value not a reference unless wrapped in another object ... can anyone explain this?

<html>
<head>
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>
<body>
<script>

 function test(arg){
   arg = arg.add($('<span/>'))
   console.log(arg);
 };

 ele = $('<div/>');
 test(ele);  // div + span in the group as expected
 console.log(ele); // only the div - the 'arg' param in function was a copy

 function test2(arg){
   arg.a = arg.a.add($('<span/>'));
   console.log(arg.a);
 };

 obj = {a:ele};
 test2(obj); // div + span in the group as expected
 console.log(obj.a); // both in the group - arg acted like a reference!

</script>
</body>
</html>
like image 992
MachineElf Avatar asked Sep 14 '10 14:09

MachineElf


People also ask

Are JavaScript objects passed by value or passed by reference?

Javascript always pass by value so changing the value of the variable never changes the underlying primitive (String or number).

Does JavaScript always pass parameters by value or by reference?

In JavaScript, all function arguments are always passed by value. It means that JavaScript copies the values of the variables into the function arguments. Any changes that you make to the arguments inside the function do not reflect the passing variables outside of the function.

Which of these data types in JavaScript when passed as function arguments are passed by reference?

So, Primitive values like number, string, boolean are passed by value while Objects and arrays are passed by reference like above said.

Does JavaScript copy object by reference?

Objects in JavaScript are passed by reference. When more than one variable is set to store either an object , array or function , those variables will point to the same allocated space in the memory. Passed by reference.


1 Answers

This is a "feature" of the .add() method. It does not modify the original jQuery object, but rather returns a new object with the added value.

Given your first example, you would need to return the arg variable and overwrite ele.

 function test(arg){
   arg = arg.add($('<span/>'))
   console.log(arg);
   return arg;  // return the new jQuery object stored in "arg"
 };

 ele = $('<div/>');
 ele = test(ele);  // overwrite the original "ele" with the returned value
 console.log(ele); 

EDIT: To give another illustration, using your code, but with .push() which modifies the original object, you will see the correct value updated in ele.

 function test(arg){
   arg = arg.push($('<span/>')[0])
   console.log(arg);  // Because .push() is being used, "arg" will reference 
                      //   the new length of the array.
 };

 ele = $('<div/>');
 test(ele);  
 console.log(ele); // Will reference jQuery object with both elements

EDIT: Once last illustration. Because .add() returns a new object, you could update both variables to point to the same value like this:

ele = arg = arg.add($('<span/>'));

Now instead of ele referencing the original, and arg referencing the new Object that was created, both variables hold a reference to the same Object in memory.

like image 138
user113716 Avatar answered Nov 14 '22 21:11

user113716