2016-06-07 20 views
7

Ich habe, was eine dumme Frage sein kann. Im folgenden Code scheint die Funktion doStuff myArray einem leeren Array zuzuweisen, aber wenn es in der Konsole versucht wird, ist myArray immer noch [2,3,4,5].Referencing Arrays in Javascript

var myArray = [2, 3, 4, 5]; 
function doStuff(arr) { 
    arr = []; 
}; 

doStuff(myArray); 
console.log(myArray)// => [2,3,4,5] 

Ferner ist eine Funktion, dass das Array modifiziert scheint gut zu funktionieren. Zum Beispiel:

function changeSecondIndex(arr){ 
     arr[2] = 25; 
} 

changeSecondIndex(myArray) 
console.log(myArray) // => [2,3,25,5] 

Könnte mir bitte jemand helfen, zu verstehen, was hier vor sich geht? Vielen Dank.

+1

Mögliches Duplikat [Javascript-Arrays Funktionen von Wert, so dass ursprünglichen Array unverändert vorbei] (http://stackoverflow.com/questions/14491405/javascript-passing-arrays-to- functions-by-value-verlassen-original-array-unaltere – ManoDestra

+1

@ManoDestra Die Frage ist hier, warum es passiert und die Frage in diesem Beitrag ist, wie man es beheben kann. Zwei verschiedene Fragen aus meiner Sicht. –

+0

Diese Frage wird vom anderen beantwortet, wenn es verstanden wird. – ManoDestra

Antwort

3

Arrays werden von Referenz in JavaScript übergeben. In den Funktionen doStuff und changeSecondIndex enthält der Parameter arr einen Referenzcode bis myArray.

In changeSecondIndex verwenden Sie diese Referenz, um auf eine Eigenschaft des Arrays zuzugreifen und sie zu aktualisieren. Das funktioniert gut, wie Sie sehen können. Aber in doStuff, was tatsächlich geschieht ist, dass Sie arr auf ein neues Array festlegen. Was das tut, ist die Tatsache, dass arr eine Referenz auf myArray war und es auf ein neues leeres Array setzt. Deshalb wird myArray nicht geändert.

+1

Wenn ich doStuff arbeiten visualisieren, sehe ich dies: 'doStuff (myArray) {myArray = []}' Aber Sie sagen, dass myArray innerhalb der doStuff-Funktion ist nicht das gleiche wie die globale var myArray? – EFH

+0

'myArray' wurde * in der Funktion' doStuff() 'als 'arr' referenziert *. Aber was geschah, war, dass diese Referenz zerstört wurde. Wenn Sie 'arr = [] 'haben, entfernen Sie den alten Wert von' arr '(eine Referenz) und setzen ihn auf einen neuen Wert (' [] '). Es mag komisch klingen, aber Sie setzen den * Wert * von 'arr', nicht' myArray'. –

+1

Ich wette, das könnte einige wirklich verwirrende Bugs verursachen. Vielleicht wurde ich (noch?) Nicht gebissen, weil ich versuche, Funktionen zu verwenden, um Werte zurückzugeben, anstatt sie an Ort und Stelle zu ändern. Etwas wie dieses: Funktion changeSecondIndex (arr) { arr [1] = 25; Rückkehr Arr; } myArray = changeSecondIndex (myArray); ..which würde das Problem überhaupt nicht zulassen.Nicht dass ich so großartig bin; Ich habe das natürlich von [woanders] (https://en.wikipedia.org/wiki/Functional_programming) bekommen. Ich bin nur froh, dass es sich so bezahlt macht, wie ich es vielleicht gar nicht bemerkt habe. –

-4

Sie haben global var myArray definiert. Und dann möchten Sie auf dieses globale Array zugreifen und es in der Funktion ändern. Ja, es überschreibt das globale Array, aber nur wenn Sie eine bestimmte Funktion haben. In deinem Fall funktioniere doStuff().

Wenn Sie doStuff() nicht aufrufen, werden die globalen Inizialisierungswerte beibehalten!

+0

Er ruft 'doStuff (myArray);', aber nichts passiert. –

+1

Es überschreibt das globale Array nicht, während es ein Element des Arrays ändert. Das ist der springende Punkt. –

4

Ihr Code neu leeres Array schafft, stattdessen können Sie bestehende Array leer mit length = 0

var myArray = [2, 3, 4, 5]; 
 
function doStuff(arr) { 
 
    arr.length = 0; 
 
}; 
 

 
doStuff(myArray); 
 
console.log(myArray)

3

Javacript Arrays sind passed by reference, was bedeutet, dass sie innerhalb von Funktionen modifiziert werden. Aus diesem Grund funktioniert Ihr zweites Code-Snippet.

Ihr erstes Code-Snippet deklariert jedoch einfach eine neue Variable arr im Rahmen der Funktion. Es ist nicht die alte Variablennamen überschreiben, es entfernt nur Ihre Fähigkeit, in die globale Variable, die Sie übergeben zu verweisen.

Sobald diese Funktion beendet wird, die neue Variable arr den Gültigkeitsbereich verlässt, und der Name Bindung fällt zurück auf den globalen Variable, die Sie zuvor deklariert haben.

Deshalb ändert doStuff() das ursprüngliche Array nicht - weil Sie tatsächlich ein brandneues Array deklariert haben, das zufällig denselben Namen im Rahmen der Funktion verwendet.

+0

* Beide * Funktionen enthalten eine Variable 'arr'. Es ist der Parameter für die Funktion. 'doStuff' setzt diese Variable auf einen Wert. Nirgends deklariert es eine neue Variable. –

+0

@RocketHazmat Nein, im ersten Snippet ist der Name 'arr' an den übergebenen Parameter gebunden. Im zweiten Snippet ist der Name' arr' an ein neues Array '[]' gebunden, da es sich um eine Definition handelt. –

+0

Aber beide Funktionen werden über 'func (myArray)' aufgerufen und beide haben 'arr' in der Funktionssignatur als Parameter. –

2

Objekte durch Verweis in JavaScript übergeben werden, wenn Sie die Funktion in Ihrem ersten Beispiel nennen, ist der Parameter arr eine Referenz auf das Objekt, das übergeben wird, wenn die Funktion

var myArray = [2, 3, 4, 5]; 
function doStuff(arr) { 
    //arr is a variable that contains the first parameter used to invoke the 
    //function, if the variable is an object then it is passed by reference 
    // 
    //Here you are assigning the variable "arr" the value of a new array 
    arr = []; 
}; 

doStuff(myArray); 
console.log(myArray)// => [2,3,4,5] 

Im zweiten Beispiel aufgerufen wird Sie ändern das übergebene Objekt, alles wird noch auf die gleiche Weise übergeben, Unterschied ist, Sie handeln auf das Objekt, das übergeben wurde, anstatt der Variablen einen neuen Wert zuzuweisen.

function changeSecondIndex(arr){ 
     //Acting on index 2 of the passed array and setting the value to 25 
     arr[2] = 25; 
} 

changeSecondIndex(myArray) 
console.log(myArray) // => [2,3,25,5] 

Wenn Sie etwas Ähnliches, was Sie im ersten Beispiel zu tun versuchen zu tun, wollte eine Art von Objekt haben könnte, die in ihm

var workingVars= {arr: [2, 3, 4, 5]}; 
function doStuff(env) { 
    // here you are assigning a new empty array to arr property of 
    // passed parameter 
    env.arr = []; 
}; 
doStuff(workingVars); 
console.log(workingVars.arr)// => [] 
1

Sie einen Zustand mit Variablen enthält don‘ Ich brauche eine Funktion und Argumente, um dies zu experimentieren. In JS [] und {} sind Objekterstellungsmuster (Literal) und bricht den Verweis. Mal sehen ...

var a = [1,2]; 
var b = [2,4]; 
var c = a; // c references a array. 
var d = b; // d references b array 
a.length = 0; // a becomes [] 
b = []; // b becomes [] 
console.log(c); // [] c still references a 
console.log(d); // [2,4] d is no more a reference to b 

Natürlich gilt das gleiche für die Objekte;

var o1 = {x:1, y:2}; 
var o2 = {x:2, y:4}; 
var p1 = o1; // p1 references o1 
var p2 = o2; // p2 references o2 
delete o1.x; 
delete o1.y; 
console.log(o1); // Object {} 
console.log(p1); // Object {} p1 still references o1 
o2 = {}; 
console.log(o2); // Object {} 
console.log(p2); // Object {x: 2, y: 4} p2 is no more a reference to o2 
0

Um zu verstehen, warum dies Sie geschieht muss zunächst daran erinnern, dass ein Array in Javascript ist ein Objekt. Der Grund Ihrer arr = [] nimmt nicht auf dem globalen Erklärung davon unberührt ist für die folgenden:

Grund 1:

arr = [] nicht ein Array löschen, es nur ein Objekt neues Array erzeugt im Speicher egal was?

So in Ihrer Funktion:

function doStuff(arr) { 
    arr = []; 
}; 

doStuff(myArray) 

Sie sind nur in myArray nehmen und eine neue leere Version davon in einem lokalen Bereich zu machen, die 2 zur Vernunft führt.

Grund 2:

Jedes neue Objekt/Variable in einer Funktion erklärt ist auf den lokalen Bereich beschränkt dieser Funktion

so:

function doStuff(arr) { 
    arr = []; 
}; 


doStuff(myArray) //logs [1,2,3,4] 

arr = []zerstört wurde an der schließenden Klammer der doStuff-Funktion kann eine außen nicht existieren.

Grund 3:

function doStuff(arr){ 

arr[2] = 25; 

} 

doStuff(myArray) 

Dies funktioniert, weil Sie myArray in arr Variable und Modifizieren einer Eigenschaft aus myArray Objekt zugreifst, dann ist dies in Javascript völlig normal.

Kurz: = Betreiber ordnet, Wieder zuweisen s und erstellen s ...

arr = [] ist eine Zuordnung zu neuen myArray Objekt in Ihrer Funktion und ist auch im Rahmen Ihrer Funktion gefangen.

arr[2] = 25 greift temporär auf myArray-Objekt zu und weist eine Eigenschaft neu zu.

this helps ..