ARRAYs im Modul verändern

- javascript
- node.js
Hallo Rolf,
ich bin jetzt vollkommen verwirrt.
Also meine Fragen:
Eine function kann Argumente erhalten. einfache Variablen werden dabei transportiert, bei ARRAYs wird nur die Adresse in das Argument transportiert. So richtig?
Jetzt Modul:
eine function in einem Modul erreiche ich so.
direct1 = require("./direct.js");
direct1.m(arg1,arg2,Prom,D,M,N,Tfile,ERGEB,FEHLER2);
Alle Argumente sind ARRAYs. Wenn diese ARRAYs verändert werden, bedeutet das, das damit auch das ARRAYs im aufrufendem Modul verändert wird, denn im aufgerufenen Module ist nur die ADRESSE bekannt. So richtig ?
Von einer Datei habe ich ein ARRAY geholt und dem ARRAY D zugewiesen:
fdNr = fs.openSync('DJSN.txt', 'r')
data = fs.readFileSync(fdNr,{ encoding: 'utf8', flag: 'r' });
if(t)
console.log("JSON.parse(data) ",JSON.parse(data))
D=(JSON.parse(data))
if(t)
console.log("D ",D)
Tatsächlich ist jetzt das ARRAY aus DJSN.txt in D
ABER im aufrufendem Modul ist D NICHT verändert.Nur durch:
var d;
d=D
module.exports.d=d
im aufrufendem Modul:D=direct1.d;
Also nichts ist mit Adresse, sondern das ARRAY D wird aus dem aufrufendem Modul in den aufgerufenen Modul transportiert,d.h in das Argument D. So weit so richtig?
Es wird noch verrückter: In dem aufgerufenem Modul verändere ich D
D[0]=irgendwas und siehe da das ARRAY D im aufrufendem Modul ist mit verändert.
Also doch AdressÜbermittlung
oder: wird nur die Gesamtveränderung des ARRAYs D im aufgerufenen Modul gesperrt. Unterarrays können jedoch verändert werden ohne module.exports
Ich hoffe, ich habe den Sachverhalt klar dargestellt und bin gespannt auf die Antwort
Effel
Hallo effel,
Also nichts ist mit Adresse, sondern das ARRAY D wird aus dem aufrufendem Modul in den aufgerufenen Modul transportiert,d.h in das Argument D. So weit so richtig?
So weit, so leider falsch. JavaScript übergibt immer Werte. Aber im Fall eines Arrays ist der Wert die Arrayreferenz. Das heißt aber nicht, dass Du auf einmal einen echten call-by-reference Parameter hättest (wie in PHP durch Einsatz von & oder in C++ durch Einsatz des ref Modifikators). Das gibt es in JavaScript schlichtweg nicht.
function replace_bad(X) {
X = [ 4,5,6];
}
let A = [1, 2, 3];
replace_bad(A);
console.log(A); // -> [1,2,3]
ist was anderes als
function replace_good(X) {
X.length = 0;
X[0] = 4;
X[1] = 5;
X[2] = 6;
}
let A = [1, 2, 3];
replace_good(A);
console.log(A); // -> [4,5,6]
Du musst genau zwischen Objektreferenz (bzw. Arrayreferenz) und Objekt (bzw. Array) unterscheiden. Das Objekt oder Array befindet sich nicht in der Variablen, sondern irgendwo im Speicher. Die Variable enthält nur die Referenz.
Deshalb kann replace_good in der übergebenen Arrayreferenz rummatschen und den Inhalt des Arrays, auf das A verweist, komplett verändern.
replace_bad hingegen weist X die Referenz auf ein anderes Array zu. Wovon aber der Aufrufer wegen der Wertübergabe der Referenz nichts mitbekommt.
Wenn Du aus der m-Funktion das Objekt zurückliefern möchtest, das JSON.parse erzeugt hat, dann hast Du theoretisch mehrere Möglichkeiten.
D = direct1.m(arg1,arg2,Prom,M,N,Tfile,ERGEB,FEHLER2);
exports.m = function(arg1,arg2,Prom,D,M,N,Tfile,ERGEB,FEHLER2) {
...
D.length = 0;
D.push(...JSON.parse(data));
}
Wenn das data-Array groß ist, könnte Dir der Spread-Operator allerdings den Stack sprengen und Du machst besser eine Schleife über die Elemente des von JSON.parse gelieferten Arrays.
exports.m = function(arg1,arg2,Prom,D,M,N,Tfile,ERGEB,FEHLER2) {
...
D.length = 0;
const dataArray = JSON.parse(data);
for (let i = 0; i < dataArray.length; i++)
D[i] = dataArray[i];
}
const mParms = { };
direct1.m(arg1,arg2,Prom,mParms,M,N,Tfile,ERGEB,FEHLER2);
console.log(mParms.D);
// in direct.js
function m(arg1,arg2,Prom,mParms,M,N,Tfile,ERGEB,FEHLER2) {
...
mParms.D = JSON.parse(data);
}
Die Klammern um JSON.parse(data) brauchst Du nicht. Aber Du solltest Dir angewöhnen, JavaScript-Statements immer mit einem Semikolon zu beenden, das kann sonst böse Überraschungen geben.
Rolf
erst mal danke,
ich werde studieren
Effel
ich habe es jetzt verstanden und es ist richtig gut:
mit:
direct1.m(arg1,arg2,Prom,D,M,N,Tfile,ERGEB,FEHLER2); rufe ich die function m im Modul direct1 auf kann dort ( mit etwas Geschick) die ARRAYs D,M,N,Tfile usw direct bearbeiten. Das ist richtig gut.
ich bedanke mich
Effel