Array-Methoden in Funktionen
mAciD
- javascript
Hallo zusammen,
ich habe ein Problem mit an Funktionen als Parameter übergeben Arrays.
function copyArray(arrayToCopy) {
return arrayToCopy.slice(0);
}
Wie ja bekannt ist, wird eine Variable, welche ein Array ist, beim Versuch diese an eine andere Variable zuzuweisen,
var array1 = new Array("1", "2", ...);
var array2 = array1;
diese nur als Referenz übergeben. Copy by Ref.
Ich will aber Copy by Value. Ich will eine exakte kopie des Arrays.
Aus diesem Grund habe ich mir obige Funktion geschrieben.
Nur fällt mir auf, dass bei mir, immer wenn ich an eine Funktion ein Array als Parameter übergebe, ich zwar noch auf die einzelnen Felder im Array zugreifen kann,
function copyArray(arrayToCopy) {
alert(arrayToCopy[3].value); // geht
return arrayToCopy.slice(0); // geht nicht mehr.
}
aber alle Objektmethoden funktionieren anscheinend nicht.
z.B.: .push, .slice, ...
Warum???
function copyArray(arrayToCopy) {
alert(arrayToCopy[3].value); // geht
return arrayToCopy.slice(0); // geht nicht mehr.}
Wo kommt den plötzlich die Eigenschaft value her? Oben hast du nur eine Reihe von Zahlen.
> aber alle Objektmethoden funktionieren anscheinend nicht.
> z.B.: .push, .slice, ...
Das sind keine Objektmethoden, sondern Arraymethoden. Ansonsten kann ich dein Beschreibung nicht nachvollziehen die Arraymethoden funktionieren einwandfrei:
~~~javascript
var x = [1,2,3,4,5];
var y = x.slice(0);
y[0] = 0;
y.push(6);
alert(x + '\n' + y);
Struppi.
Hallo Struppi,
beschränken wir uns doch auf das Problem.
(arrayToCopy[3] oder arrayToCopy[3].value ist mir jetzt erst mal egal, und mir ist auch egal ob es jetzt Objekt- oder Arraymethoden sind.
Dachte nur, das ein Array ein Objekt ist, weil ja mit new erzeugt, und ich dann von den Methoden des Objekts arrayToCopy (ist ja ein Array) eben von Objektmethoden spreche.
Wenn es nun Arraymethoden sind dann sage ich eben Arraymethoden dazu.
Mein Problem ist nun aber, daß folgendes funktioniert:
var einArray = new Array("A","B","C"); // ein neues Array erzeugt
var kopiertesArray = einArray.slice(0); // array kopiert by Value
Aber das hier funktioniert nicht:
var einArray = new Array("A","B","C"); // ein neues Array erzeugt
var kopiertesArray = copyArray(einArray); // Fehlermeldung.
function copyArray(arrayToCopy) {
return einArray.slice(0);
}
Kann mir jemand beantworten, warum das nicht klappt. Ich weiß es nicht.
Und gleich vorab: Wahrscheinlich verwende ich nicht die richtigen Fachausdrücke. Sorry. Und vielleicht habe ich auch irgendwo ein Semikolon vergessen.
Mir geht es darum, warum ich auf die Arraymethoden bei als Parameter übergenes Array in funktionen nicht mehr zugreifen kann.
Michal
beschränken wir uns doch auf das Problem.
Das wäre nett.
(arrayToCopy[3] oder arrayToCopy[3].value ist mir jetzt erst mal egal, und mir ist auch egal ob es jetzt Objekt- oder Arraymethoden sind.
Nein, das ist nicht egal.
Dachte nur, das ein Array ein Objekt ist, weil ja mit new erzeugt, und ich dann von den Methoden des Objekts arrayToCopy (ist ja ein Array) eben von Objektmethoden spreche.
Das stimmt, ein Array ist ein Object, aber ein Object ist kein Array.
Wenn es nun Arraymethoden sind dann sage ich eben Arraymethoden dazu.
wenn du aber ein Object hast, dann kannn es keine Arraymethoden.
Mein Problem ist nun aber, daß folgendes funktioniert:
Mein Problem ist, das funktioniert bei mir.
Kann mir jemand beantworten, warum das nicht klappt. Ich weiß es nicht.
Ich auch nicht, da du nicht sagst was du wirklich machst udn dich nicht auf dein wirkliches Problem beschränkst.
Mir geht es darum, warum ich auf die Arraymethoden bei als Parameter übergenes Array in funktionen nicht mehr zugreifen kann.
Kannst du ohne Probleme.
Struppi.
Danke Struppi.
Anscheinend habe ich mich unklar ausgedrückt. Mir ist klar, daß ich kein Programmiergott bin (nicht mal ansatzweise), und mir ist auch klar, daß Du besser Programmieren kannst als ich (nehme ich mal an).
Nun warst du so nett mich darauf hinzuweisen.
Ich dachte echt, ich habe mein Problem geschildert. Wohl ehr nicht. Sorry.
Auch dachte ich, ich übergebe an die selbstgebaute Array-Kopier-Funktion ein Array, und wende dann die Methode (oder was auch immer) des Arrays slice an, um letztendlich ein neues Array zurückzugeben.
Auch dachte ich, es wäre eigentlich egal, ob die Syntax ganz genau stimmt, denn es ging mir ums prinzipielle anwenden von Methoden aus Funktionen heraus.
Das Funktioniert bei Dir, bei mir aber nicht. Somit ist mir nicht wirklich geholfen.
Mir ist auch klar, daß ich irgendwo einen Fehler im Code habe, und daß ich den höchstwahrscheinlich selbst zu verantworten habe.
Aber was soll ich mache.
Sollte ich dich in irgeneiner Form beleidigt, gekränkt, oder sonst irgendwie verletzt haben, bitte ich um Entschuldigung. Sorry.
Michael.
Auch dachte ich, ich übergebe an die selbstgebaute Array-Kopier-Funktion ein Array, und wende dann die Methode (oder was auch immer) des Arrays slice an, um letztendlich ein neues Array zurückzugeben.
Genau hier liegt dein Problem und auch unseres, da du uns einfach nciht verraten willst, wie dein Array aussieht.
Auch dachte ich, es wäre eigentlich egal, ob die Syntax ganz genau stimmt, denn es ging mir ums prinzipielle anwenden von Methoden aus Funktionen heraus.
Von der Syntax hat hier niemand gesprochen, die ist i.O.
Mir ist auch klar, daß ich irgendwo einen Fehler im Code habe, und daß ich den höchstwahrscheinlich selbst zu verantworten habe.
Nein hast du nicht. In dem Code, den du uns gezeigt hast, ist kein Fehler.
Aber was soll ich mache.
Uns zeigen woher das Array kommt und wie du es definierst. So wie es aussieht ist es kein Array.
Sollte ich dich in irgeneiner Form beleidigt, gekränkt, oder sonst irgendwie verletzt haben, bitte ich um Entschuldigung. Sorry.
Wie kommst du darauf? Du machst es mir nur etwas schwer dir bei deinem Problem zu helfen, aber das kränkt mich nicht.
Struppi.
Hallo Struppi, danke für deine Hartnäckigkeit ;o)
ich habe, ist dir vielleicht entgangen, einen neuen Zweig in diesem Thread angelegt. Dort habe ich mehr meines Codes gezeigt. Vielleicht hilft das.
Michael.
Diese Fehlermeldung bekomme ich, wenn ich die Funktion generateSortTable ausführe:
TypeError: arrayToCopy.slice is not a function
// Array kopieren
function copyArray(arrayToCopy) {
return arrayToCopy.slice(0);
}
// Array mit Sortierreihenfolge erzeugen
// -
function generateSortTable(unsortAr, sortType) {
try {
// Array für Sortier-Reihenfolge anlegen
var sortTable = new Array();
// Array kopieren
var unsortAr = copyArray(unsortAr);
// Array sortiern
switch (sortType) {
case "numA":
var sortedAr = unsortAr.sort(numComparisonAsc);
break;
case "numD":
var sortedAr = unsortAr.sort(numComparisonDesc);
break;
case "string":
var sortedAr = unsortAr.sort(stringComparison);
break;
}
} catch (e) {
alert(e);
}
}
Anmerkung: die Funktion ist noch nicht ganz ausprogrammiert, aber es scheitert schon am kopieren des Arrays. An den Sortier-Vergleichsfunktionen lieft es nicht.
Diese Fehlermeldung bekomme ich, wenn ich die Funktion generateSortTable ausführe:
TypeError: arrayToCopy.slice is not a function
Dann ist arrayToCopy.kein array, aber das sagte ich dir bereits in meinem ersten Posting. Du wolltest aber auf die Frage nicht eingehen.
Struppi.
gruss mAciD,
Diese Fehlermeldung bekomme ich, wenn ich die Funktion generateSortTable ausführe:
TypeError: arrayToCopy.slice is not a function
in diesem fall bekommt schon die funktion [generateSortTable] ein ungueltiges
[unsortAr] argument zugewiesen.
ausserdem wuerde ich die hilfsfunktion [copyArray] so umschreiben, dass diese
unabhaengig von gueltigen/ungueltigen argumenten immer einen wert zurueckgibt,
ohne, wie in dem von Dir beschriebenen fall, mit einer fehlermeldung abzubrechen.
var /*Array.*/makeShallowCopy = (function (arr) {
//return arr.slice();
//return ((arr && (typeof arr.slice == "function") && arr.slice()) || []);
//return ((arr && (typeof arr.slice == "function") && arr.slice()) || null);
//return ((arr && (typeof arr.slice == "function") && arr.slice()) || window.undefined);
return ((arr && (typeof arr.slice == "function") && arr.slice()) || (arr && arr.slice));
});
Anmerkung: die Funktion ist noch nicht ganz ausprogrammiert, aber es scheitert schon
am kopieren des Arrays.
exakt - siehe oben.
so long - peterS. - pseliger@gmx.net
in diesem fall bekommt schon die funktion [generateSortTable] ein ungueltiges
[unsortAr] argument zugewiesen.
var A_TextPCountry = document.getElementsByName("PB_TextPCountry");
Dieses globale Array lege ich zu Programmbeginn an. Ist in keiner Funktion.
Ich habe im HTML-Code in diversen <INPUT> Tags diverse Informationen geschrieben (per %SEARCH{}% einer FOS-WIKI).
Diese lese ich zu beginn ein. Eben in diese Arrays.
Dann habe ich folgende Funktion, um den Sortiervorgang zu starten:
function sortOutputByCountry(){
generateSortTable(A_TextPCountry,'string');
}
Welche wiederum meine Sortierfunktion aufruft, mit bekanntem effekt.
Ach ja, die obige Funktion wird über einen Button um HTML-Gerüst per onClick-Event ausgeführt.
Was mache ich falsch.
Moin!
var A_TextPCountry = document.getElementsByName("PB_TextPCountry");
Dieses globale Array lege ich zu Programmbeginn an. Ist in keiner Funktion.
Da hast du dein Problem!
getElementyByName liefert dir KEIN Array zurück, sondern eine NodeList, auf die du mit Indices genauso zugreifen kannst, wie auf ein Array, die aber eben NICHT die Methode slice implementiert hat.
Was mache ich falsch.
Es ist also genau so, wie Struppi es meint: Du hast kein Array.
- Sven Rautenberg
Danke, gut das es Fachmänner wie euch gibt. (ist ernst gemeint)
Für euch klingt sowas wahrscheinlich banal, aber für mich kostete diese Erkenntnis einige Stunden an Try and Error.
Moin!
var A_TextPCountry = document.getElementsByName("PB_TextPCountry");
Dieses globale Array lege ich zu Programmbeginn an. Ist in keiner Funktion.
Da hast du dein Problem!
getElementyByName liefert dir KEIN Array zurück, sondern eine NodeList, auf die du mit Indices genauso zugreifen kannst, wie auf ein Array, die aber eben NICHT die Methode slice implementiert hat.
Was mache ich falsch.
Es ist also genau so, wie Struppi es meint: Du hast kein Array.
- Sven Rautenberg
var A_TextPCountry = document.getElementsByName("PB_TextPCountry");
Dieses globale Array lege ich zu Programmbeginn an.
Eine einfache Lösung für dein Problem wäre:
var A_TextPCountry = Array.prototype.slice.call(document.getElementsByName("PB_TextPCountry"));
leider machen da nicht alle IE Versionen mit, d.h. für die musst du die Nodelist von Hand umkopieren.
Struppi.
Werde ich mal Prüfen.
Wir verwenden Firefox, und es ist auch sichergestellt daß Firmeninter unser WIKI-System nur mir Firefox genutzt wird.
Ich bin schon froh, daß der Fehler, wie du schon sagtest, am vermeintlichen Array lag, welches ja tatsächlich keines ist.
Man stellt ja schnell (ich zumidest) seinen kompletten Code in Frage.
var A_TextPCountry = document.getElementsByName("PB_TextPCountry");
Dieses globale Array lege ich zu Programmbeginn an.
Eine einfache Lösung für dein Problem wäre:
var A_TextPCountry = Array.prototype.slice.call(document.getElementsByName("PB_TextPCountry"));
leider machen da nicht alle IE Versionen mit, d.h. für die musst du die Nodelist von Hand umkopieren.Struppi.
hallo again mAciD,
var A_TextPCountry = document.getElementsByName("PB_TextPCountry");
Dieses globale Array lege ich zu Programmbeginn an.
hier steckt auch schon der fehler - [A_TextPCountry] ist kein array-
objekt, sondern ein sogenanntes [NodeList]-objekt bzw. in der fehlerhaften
implementierung von mozilla ein [HTMLCollection]-objekt.
diese listen lassen sich zwar wie arrays mit >>for (var i=0 ...)<<
iterieren, implementieren selber aber keinerelei array-methoden.
eine methode/funktion, die aus listen-strukturen native array-objekte
erzeugt, muss im kern anders geschrieben werden, als die beiden in den
vorherigen postings vorgestellten methoden/funktionen.
im modernen kern etwa so:
Array.make = (function (list) {
return Array.prototype.slice.call(list);
});
dieser ansatz scheitert aber schon im msie, da die delegation an
das prototypische [slice] mit fehler abbricht. das gleiche gilt
fuer strings, die ja ebenfalls als listen implementiert sein
koennten (dort versagt auch opera). browseruebergreifend ist nur
die delegation von[arguments]-arrays und nativen array-objekten
verlaesslich.
werbung in eigener sache:
ein wasserdichtes und performantes [Array.make]
laesst sich auf refactory.org finden.
so long - peterS. - pseliger@gmx.net