Malleus' Tutorials:
Javascript 1.6

Version: 0.31 ( 21.10.2006 )

© Frank Hammerschmidt

Forum  - Javascript Spiele  - Javascript FAQ -  Impressum


Mozilla hat mit Firefox 1.5 den Javascript Standard erweitert und die Version 1.6 implementiert.

Es wurden unter anderem neue Array-Methoden eingeführt, die das Suchen und Durchlaufen des Arrays vereinfachen sollen:

indexOf -  lastIndexOf -  every -  some -  filter -  forEach -  map

Da man davon ausgehen kann, daß die anderen Browserhersteller nicht unbedingt "zügig" das neue Javascript als Standard anerkennen werden, wird es wohl "etwas" dauern bis er umgesetzt wird.

Für uns ist das ganze aber kein großes Problem!

Wir implementieren die neuen Methoden einfach selbst:


Inhaltsangabe

 

1. Array-Methoden:

 

indexOf( arrayValue [, startIndex ] )

berechnet den Array-Index des angegebenen Array-Wertes. Hierbei gibt der optionale Parameter "startIndex" die Startposition innerhalb des Arrays an.

lastIndexOf( arrayValue [, startIndexVonHinten ] )

berechnet ausgehend vom Ende des Arrays das gleiche wie "indexOf".

var myNumbers=new Array( 19, 5, 20, 100, 50, 23, 5, 49, 78 );

myNumbers.indexOf(5)) == 1
myNumbers.indexOf(5,3)) == 6
myNumbers.lastIndexOf(5)) == 6
myNumbers.lastIndexOf(5,3)) == 1
 

2. Array-Iterationen

Es wurden mehrere Iterations-Methoden eingeführt, die als Parameter eine Funktion mit drei optionalen Parameter besitzen:

  • der i-te Array-Wert
  • der i-te Array-Index
  • das Array-Objekt selbst

 

every( testFunction )

gibt den Wert "true" zurück, wenn der Test für alle Array-Werte erfolgreich war.  

some( testFunction )

gibt den Wert "true" zurück, wenn es mindestens einen Array-Wert gibt, für den der Test erfolgreich war.  

filter( testFunction )

erzeugt ein Array mit Werten für die der Test erfolgreich war.
var myNumbers=new Array( 19, 5, 20, 100, 50, 23, 5, 49, 78 );

function isLess1000( myValue, myIndex, myArray )
{
	return ( myValue < 1000 )
};

function isGreater50( myValue, myIndex, myArray)
{
	return  ( myValue > 50 )
};

if ( myNumbers.every( isLess1000 ) )
	 alert( "Alle Zahlen sind kleiner als 1000" );

if ( myNumbers.some( isGreater50 ) )
	 alert( "Es gibt Zahlen, die größer als 50 sind!" );

var result = myNumbers.filter( isGreater50 );
alert( "Die folgenden Zahlen sind größer als 50" );
for ( var i = 0; i < result.length; i++ )
	 alert( result[ i ] )
 

forEach( callFunction )

ruft für jeden Array-Wert die Funktion "callFunction" auf.
var myFriends=new Array( "Stefan", "Thomas", "Martin" );

function sayHello( myValue, myIndex, myArray)
{
	alert(" Hallo "+ myValue );
};

myFriends.forEach(sayHello);
 

map( execFunction )

führt für jeden Array-Wert die Funktion "execFunction" aus und speichert die dazugehörigen Ergebnisse in einem Array, welches als "return"-Wert zurückgegeben wird.
var myNumbers=new Array( 1.2, 5.6, 20.9, 100.1 );

function roundIt( myValue, myIndex, myArray)
{
	return Math.round( myValue );
};

var result = myNumbers.map( roundIt );
for (var i = 0; i < result.length; i++ )
	 alert( myNumbers[ i ] + " rounded =  " + result[ i ] );
 

3. Crossbrowser Implementierung der neuen Javascript 1.6 Methoden (Teil 1 )

Wie implementiert man nun für alle "NichtFireFox1.5"-Browser die neuen Array-Methoden?

Ganz einfach: Man überprüft zuerst, ob die Array-Methode bereits existiert, d.h. die Methode wurde bereits vom Browserhersteller bereitgestellt. Ist dies nicht der Fall, wird dem Array-Objekt die neue Methode durch "Prototyping" hinzugefügt. Innerhalb dieser Prototype-Funktion kann man nun mit Hilfe von "this" auf das echte Array-Element zugreifen, d.h. this[0] entspricht dem ersten Arraywert und this.length ergibt die Anzahl der Arrayeinträge.

if ( typeof Array.indexOf != "function" )
	Array.prototype.indexOf = function( myValue, startIndex )
	{
		if ( startIndex == null )
			startIndex = 0;

		for ( var i = startIndex; i < this.length; i++ )
			if ( this[ i ] == myValue )
				return i;

		return -1;
	};

if ( typeof Array.lastIndexOf != "function" )
	Array.prototype.lastIndexOf = function( myValue, startIndex )
	{
		if ( startIndex == null )
			startIndex = this.length-1;

		for ( var i = startIndex; i >= 0; i-- )
			if ( this[ i ] == myValue )
				return i;

		return -1;
	};

if ( typeof Array.every != "function" )
	Array.prototype.every = function( myFunction )
	{
		for ( var i = 0; i < this.length; i++ )
			if ( !myFunction( this[ i ], i, this ))
				return false;

		return true;
	};

if ( typeof Array.some != "function" )
	Array.prototype.some = function( myFunction )
	{
		for ( var i = 0; i < this.length; i++ )
			if ( myFunction( this[ i ], i, this ))
				return true;

		return true;
	};

if ( typeof Array.filter != "function" )
	Array.prototype.filter = function( myFunction )
	{
		var result = [];

		for ( var i = 0; i < this.length; i++ )
			if ( myFunction( this[ i ], i, this ))
				result.push( this[ i ] );

		return result;
	};

if ( typeof Array.forEach != "function" )
	Array.prototype.forEach = function( myFunction )
	{
		for ( var i = 0; i < this.length; i++ )
			myFunction( this[ i ], i, this );

		return true;
	};

if ( typeof Array.map != "function" )
	Array.prototype.map = function( myFunction )
	{
		var result = [];

		for ( var i = 0; i < this.length; i++ )
			result.push( myFunction( this[ i ], i, this ) );

		return result;
	};
Testseite - Download Javascript16 Library ( 1. Version )  

4. Array-Iterationen mit Object-Bezug

Ansteller "einfacher" Funktionen ist es auch möglich, Methoden eines Objektes den neuen Array-Methoden zu übergeben. Da hier jedoch der Contextbezug innerhalb der Funktion (this) fehlt, wird dieser als zweiter Parameter hineingereicht:

Beispiel:

some( execFunction, myObject )

var conditions = new Object();

conditions.isGreaterValue = 50;

conditions.isGreater = function( myValue, myIndex, myArray)
{
	return  ( myValue > this.isGreaterValue )
};


var myNumbers = new Array( 19, 5, 20, 100, 50, 23, 5, 49, 78 );

if ( myNumbers.some( conditions.isGreater, conditions ) )
		 alert( "Es gibt Zahlen, die größer als 50 sind!" );

Die dazugehörige Implementierung sieht wie folgt aus:

if ( typeof Array.some != "function" )
	Array.prototype.some = function( myFunction, context )
	{
		for ( var i = 0; i < this.length; i++ )
		{
			if ( !context )
				context=window;

			context._some_ = myFunction;

			if ( context._some_( this[ i ], i, this ))
				return true;
		};

		return true;
	};

Was tue ich hier?

  1. Wenn kein Kontext (=Object) übergeben wurde, wähle ich mir als Kontext das aktuelle "window"-Objekt.
  2. Meinem Kontext füge ich eine Methode "_some_" hinzu. Diese Methode zeigt auf die "übergebene" Funktion bzw. Methode.
  3. Nun rufe ich die Funktion mit seinem dazugehörigen Kontext auf, also entweder "window.functionName" oder "object.functionsName". Somit ist gewährleistet, daß innerhalb der Methode "this" auf das richtige Objekt zeigt.

( Die Methoden "every","filter","map" und "forEach" sind ähnlich aufgebaut und werden daher nicht gesondert aufgeführt. )

Testseite - Download Javascript16 Library ( 2. Version )