2010-09-14 4 views
6

Mein Verständnis: in Javascript Objekte und Arrays erhalten als Referenzen nicht Werte für Funktionsargumente. Eine jQuery-Gruppe ist ein Objekt und sollte daher als Referenz übergeben werden.jQuery Objekt als Argument an die Funktion übergeben ist Wert kopieren nicht Referenz?

Allerdings finde ich im Testskript unten, dass etwas Seltsames vor sich geht; Die jQuery-Gruppe benimmt sich wie ein Wert, keine Referenz, es sei denn, sie ist in ein anderes Objekt eingepackt ... Kann das jemand erklären?

<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> 

Antwort

3

Dies ist ein "Merkmal" der .add() Methode. Es ändert nicht das ursprüngliche jQuery-Objekt, sondern gibt ein neues Objekt mit dem hinzugefügten Wert zurück.

In Ihrem ersten Beispiel müssten Sie die Variable zurückgeben und ele überschreiben.

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: ein weiteres Beispiel zu geben, Ihren Code verwenden, aber mit .push(), die das ursprüngliche Objekt ändert, werden Sie den richtigen Wert in ele aktualisiert sehen.

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: Einmal letzte Abbildung. Da .add() ein neues Objekt zurückgibt, könnten Sie beide Variablen aktualisieren, um den gleichen Wert wie folgt Punkt:

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

Jetzt statt ele die ursprüngliche Referenzierung und arg das neue Objekt verweisen, die erstellt wurde, beide Variablen halten ein Referenz auf das gleiche Objekt im Speicher.

+1

* Dies ist ein "Feature" der .add() - Methode. * - macht es so, als wäre es mit einer anderen Methode möglich, wenn es so codiert wäre. Tatsache ist, dass ein neuer Wert auf die Variable 'arg' innerhalb der Funktion gesetzt wird und nicht die 'ele'-Variable im äußeren Bereich ändert, von der das OP denkt, dass sie "per Referenz" übergeben wurde. –

+0

@Andy E - Eigentlich ist es möglich. Ich gebe ein anderes Beispiel mit dem ursprünglichen Code von OP, aber mit 'push()' statt dessen. Es ändert das jQuery-Objekt korrekt und "ele" verweist auf das geänderte Objekt. – user113716

+0

@Andy E - Ok, vielleicht verstehe ich die korrekte Bedeutung von * "pass by reference" * falsch. Wenn Sie eine Variable übergeben, übergeben Sie einen Verweis auf ihren Wert, von dem ich glaube, dass er genauso in anderen objektorientierten Sprachen wie Java angezeigt wird. Täusche ich mich? In jedem Fall veranschaulichen beide Lösungen die richtigen Konzepte innerhalb von Javascript. – user113716

0

Die zwei von Ihnen durchgeführten Tests sind nicht identisch. Der erste setzt eine Variable arg auf den Wert arg.add(...), während der zweite eine Eigenschaft auf arg mit dem Namen a auf den Wert arg.a.add(...) setzt. In JavaScript "per Referenz" zu übergeben, ist nicht wirklich dasselbe wie in anderen Sprachen (in der Tat würden einige nicht zustimmen, dass es wirklich Pass-by-Reference ist). Wenn Sie eine Variable übergeben, deren Typ ein Objekt ist, haben Sie einen Verweis auf seinen Wert und nicht auf die ursprüngliche Variable. Wenn Sie arg = arg.add(...) festlegen, legen Sie einen neuen Wert für die Variable fest und überschreiben den vorherigen Wert. Dadurch wird die übergebene Variable nicht geändert, da Sie keine Referenz darauf haben. Sie haben nur einen Verweis auf ihren Wert (das Objekt).

Verwandte Themen