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.l开发者_开发百科og(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>
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.
The two tests you performed aren't the same. The first one sets a variable arg
to the value arg.add(...)
, while the second one set's a property on arg
named a
to the value arg.a.add(...)
. Passing "by reference" in JavaScript isn't really the same as it is in other languages (in fact, some would disagree that it is really pass-by-reference). When you pass an variable whose type is an object, you have a reference to its value and not to the original variable.
When you set arg = arg.add(...)
, you are setting a new value for the arg
variable and overriding its previous value. This will not modify the variable that was passed in, because you don't have a reference to it, you only have a reference to its value (the object).
精彩评论