JavaScript ÜbungsConcat Funktionsaufruf

violentviper

Lt. Commander
Registriert
Mai 2008
Beiträge
1.685
Hallo,

ich bin gerade dabei mit JavaScript rumzuspielen um es zu lernen. Ich dachte ich schreibe mir meine eigene Arrayconcat Funktion. Ich weiß das es eine gibt, auf welche ich mich auch beziehe. Es geht nur um die Übung.
Hab auch eine funktionierende Lösung hinbekommen, jedoch ist es streng gesehen nicht das gleiche wie die Concatmethode. Unten seht ihr meinen Code, einmal über die herkömmliche concat() und dann über meine selbstgeschriebe. Die Outputs in der Entwicklerkonsole sind jedesmal gleich.

Was mich stört ist der Funktionsaufruf meiner eigenen Concat Funktion. Ich rufe meine funktion ja so auf :

myConcat(Array1,Array2) , die richtige Concat Funktion ruft man aber so auf --> Array1.concat(Array2) . Man fasst also nur ein Array als Übergabeparameter. Jedoch weiß ich nicht wie ich sowas bewerkstelligen soll, ich müsste ja quasi auf das Objekt vor der runden Klammer irgendwie zugreifen. Und dann mir den Wert schnappen und in meiner eigenen Funktion wieder dazuaddieren.

Ich würde gerne konkret schreiben können: Array1.myConcat(Array2) , also so wie bei der normalen Concat auch.

Geht das irgendwie einfach, oder wäre das zu komplex ?

Code:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Übungsseite ConCatArrays</title>

<script>

var Array1 = ["Klingonen", "Cardassianer","Ferengi"];
var Array2 = ["Föderation", "Gorn", "Borg"];

//über die Concat Methode 

var notMyConcat = Array1.concat(Array2);

console.log("Nicht mein Concat " + notMyConcat)



//--- Selbstgeschriebene ConcatFunktion---

function myConcat ( arr1 , arr2) {

	var x = arr1+","+arr2;
	return x;

}
console.log("Eigenes Concat " + myConcat(Array1,Array2));

</script>
</head>
<body>
TESTSEITE 
</body>
</html>
 
var notMyConcat = Array1.concat(Array2) -> passt doch?!


Array1.myConcat(Array2) -> wieso?

in C# wäre das eine funktion und das andere eine methode....man kann beides nicht auf die selbe art und weise verwenden
 
tnoay schrieb:
var notMyConcat = Array1.concat(Array2) -> passt doch?!


Array1.myConcat(Array2) -> wieso?

in C# wäre das eine funktion und das andere eine methode....man kann beides nicht auf die selbe art und weise verwenden

Also kann man keine eigene Methode schreiben in JavaScript? Das man sozusagen die Funktion von der Syntax her gleich verwenden kann, wie die Methode.
 
Doch das kann man, aber dafür sollte man verstanden haben - was auch Yuuri schon geschrieben hat - wie das ganze Prototyping und handling von Funktionen und Funktionsaufrufen funktioniert ;-).

So wie du deine Funktion myConcant definiert hast wird diese an das "window-Objekt" angefügt. Wenn du möchtest dass die "Array-Klasse" aber über die Funktion myConcat verfügt, musst du diese an den Array Prototypen anhängen z.B. so:

Code:
Array.prototype.myConcat = function (arrayToConcat) {
//Logik hier rein
}

Ich garantiere jetzt aber nicht dass das so auch zu 100% funktioniert.. dafür habe ich schon zu lange kein JavaScript mehr ohne jQuery benutzt :>.
 
Zuletzt bearbeitet:
JP-M schrieb:
Ich garantiere jetzt aber nicht dass das so auch zu 100% funktioniert.. dafür habe ich schon zu lange kein JavaScript mehr ohne jQuery benutzt.
Wenn man JQuery nutzt, sollte tunlichst davon abgeraten werden, den Prototype von Object oder Array zu verändern, denn das kann die gesamte Logik von JQuery behindern (gefällt mir auch nicht, ist aber nun mal so, hoffentlich ändert sich das in zukünftigen Versionen).

Der Ansatz von JP-M ist schon korrekt so, this bezieht sich dann aufs aktuelle Objekt/Array und weitere kommen dann über die im Funktionsaufruf definierten Variablen bzw. gar über die arguments-Variable dazu (bspw. [].myConcat( [1,2,3], [4,5,6], [7,8,9] ) o.ä.).

@ tnoay: Er will es aber selbst bauen und dafür ist das Beispiel doch gut gewählt. In C# gibts übrigens Extension-Methods, was prinzipiell das Gleiche bewirkt.
Code:
static public class Ext
{
	static public string anfuegen( this string str, params string[] OtherStrings )
	{
		string r = str;
		foreach( string s in OtherStrings )
		{
			r += s;
		}
		return r;
	}
}

// ...

"test".anfuegen( "1", "2", "3" ); // = test123
Verhält sich genauso wie in JS, nur arbeiten die beiden Methoden intern natürlich unterschiedlich.
Code:
string.prototype.anfuegen = function( OtherStrings )
{
	var v = this;
	for( var i in arguments )
	{
		if( arguments.hasOwnProperty( i ) )
		{
			v += arguments[i];
		}
	}
	return v;
};
 
Um das Verhalten von concat besser zu imitieren, empfiehlt es sich die Parameter nicht explizit anzugeben um so auch mit mehreren möglichen Aufrufen zurecht zu kommen.
Code:
Array.prototype.myPrototypeConcat = function() { 
   var result = this;
   for (var i = 0; i < arguments.length; i++) {
      result += arguments[i];
   }
   return result;
}
var Array3 = ["Kirk", "Spock", "R2D2"];
console.log("myPrototypeConcat " + Array1.myPrototypeConcat());
console.log("myPrototypeConcat " + Array1.myPrototypeConcat(Array2));
console.log("myPrototypeConcat " + Array1.myPrototypeConcat(Array2,Array3));
 
Zuletzt bearbeitet: (Code-Formatierung)
MoOderSo schrieb:
Um das Verhalten von concat besser zu imitieren, empfiehlt es sich die Parameter nicht explizit anzugeben um so auch mit mehreren möglichen Aufrufen zurecht zu kommen.
Code:
Array.prototype.myPrototypeConcat = function() { 
   var result = this;
   for (var i = 0; i < arguments.length; i++) {
      result += arguments[i];
   }
   return result;
}
var Array3 = ["Kirk", "Spock", "R2D2"];
console.log("myPrototypeConcat " + Array1.myPrototypeConcat());
console.log("myPrototypeConcat " + Array1.myPrototypeConcat(Array2));
console.log("myPrototypeConcat " + Array1.myPrototypeConcat(Array2,Array3));

Der Code wird aber so nicht funktionieren, weil du Array 1 und 2 nirgends definierst.
 
Das ist mir schon klar. Ich wollt hier nur nicht nochmal deinen Code posten, wo du die Arrays schon definiert hattest. ;)
 
Native Prototypen sollte man möglichst nie erweitern (bzw. nur wenn man wirklich weiß was man tut). Das hat nicht nur große Performance Nachteile (die js VM's können dadurch schlechter optimieren) sondern ist recht risikoreich was Bugs angeht. Fremder Code läuft normalerweise im gleichen globalen Namespace und sieht damit auch die eigenen Änderungen.

Code:
Array.prototype[0] = "opps";

[][0] // => "opps"

Man kann in js (noch) nicht richtig von eingebauten "Spezialobjekten" wie Arrays erben und Subklassen erstellen. In Zukunft wird es mal gehen (der neuste js Standard enthält neue Techniken um "Klassen" zu erstellen, welche Native Typen erweitern) aber das können aktuelle Browser noch nicht.

Entweder schreibt man normale Funktionen, welche einfach als erstes Argument den Ursprungswert nehmen, oder man verwendet Tricks wie jQuery's $() Funktion oder auch Underscores chain. Die erstellen im Grunde einen "Wrapper" um einen Wert (einfach eine Objekt Instanz), der eine Referenz zum dem Wert + eigene Methoden enthält.

Zum zusammenfügen von Arrays (oder Objekten generell) kann man übrigens nicht "+" verwenden. Das ist nur für Zahlen und Strings zuständig.

Code:
console.log([1,2] + [3,4]) // Gibt einen String aus! '+' konvertiert zu die Argumente zu Strings, etwa so
console.log(String([1,2]) + String([3,4]))

console.log([1,2].concat([3,4])) // Gibt eine Array aus
console.log(String([1,2].concat([3,4]))) // Wie Zeile 2 aber nicht wie Zeile 4
 
Zurück
Oben