Posts mit dem Label webdevelopment werden angezeigt. Alle Posts anzeigen
Posts mit dem Label webdevelopment werden angezeigt. Alle Posts anzeigen

2012-06-20

Nicht immer Responsive Web Design


Responsive Web Design ist in aller Munde und wird derzeit sehr stark gehyped. Auch Luke W ist Befürworter von Responsive Web Design - dennoch hatte er gute Gründe für die mobile Variante von Bagcheck ein eigenes Interface zu entwickeln. Diese Gründe liefert er in seinem Blog-Post "Why Separate Mobile & Desktop Web Pages?", die ich hier kurz aufgreifen möchte:

Oberstes Gebot bei dem Projekt war Site Performance und Geschwindigkeit. Unter diesen Prämissen - und der generellen Philosopie: "Nur so viel wie nötig" - findet Luke vier Gründe:


Sourcecode Reihenfolge


Der Kern von Responsive Web Design ist die Auslieferung einer einzigen (HTML-) Website-Variante an alle Geräte. Die Anzeige des Contents passt sich dann entsprechend den Möglichkeiten des Gerätes an (in der Regel durch CSS gesteuert).

HTML Markup hat aber eine Reihenfolge, die bestimmt, in welcher Reihenfolge was gerendert wird. Diese kann natürlich mittels JavaScript manipuliert werden - aber dies zuverlässig für alle Geräte umzusetzen ist eine herausfordernde Aufgabe.

Ein einfaches Beispiel ist ein Site-weites Navigationsmenü. Während es auf Desktop-Größen in der Regel oben angeordnet ist, ist es für mobile Geräte, insbesondere in Smartphone Größe üblich, diese Menüs ans Ende der Seite zu rendern.


Medien


Responsive Web Design setzt sich auch mit Medien auseinander. Grafiken und Videos werden auf kleineren Displays kleiner dargestellt. Allerdings ist skalieren hier nicht unbedingt die beste Wahl. Erstens werden dabei unnötig Große Dateien übertragen (gerade an mobile Geräte mit evtl. nicht besonders schneller Anbindung). 
Anm.: Hier kommt zum Beispiel auch die iOS Retina--Display Diskussion ins Gespräch, da es sich für diese Geräte anbietet - genügend Bandbreite vorausgesetzt - hochauflösende Grafiken nachzuladen. (Siehe z.B. What the New iPad’s Retina Display Means for Web Developers. - Danke für den Tipp Moritz)

Zweitens kann es durchaus sinnvoll sein, dass man die Medien für unterschiedliche Display-Größen unterschiedlich aufbereitet: Große Grafiken mit vielen Details vs. kleine Grafiken mit weniger Details, also einem anders gewählten Ausschnitt.


URL-Struktur


Anm. vorab: Wie ich in Mobile und Content oder besser Content vs. Mobile? geschrieben habe, gibt es nur ein Web und ein und der selbe Content sollte auch unter ein und der selben URL zu erreichen sein. Aber:

Es gibt Situationen, in denen eine eigene URL-Struktur für kleinere Screens durchaus Sinn ergibt: Luke nennt als Beispiel eine Seite mit User-Content, Kommentaren dazu, Updates und "Likes". Dies passt alles zusammen gut auf eine Desktop-Seite und ist zum Beispiel unter der URL bagcheck.com/bag/7811 zu erreichen. Für kleinere Bildschirme ist es aber durchaus sinnvoll, einige der Informationen auf Unterseiten auszulagern, die dann unter den URLs bagcheck.com/bag/7811/updates, bagcheck.com/bag/7811/comments und bagcheck.com/bag/7811/likes zu erreichen sind.


Anwendungsdesign


Ein letzter entscheidender Punkt, der zu bedenken ist, ist folgender: Auf kleinen Displays kann es sinnvoll sein, längere Tasks von einer Seite auf mehrere zu verteilen.



2011-09-05

Robots Exclusion Standard: Ein Test

Für einen Test muss ich hier mal zwei (Sub-)Domains verlinken. Über diese Links werden die beiden Domains dann von den Search Engine Crawlern gefunden. Da bei beiden Domains die robots.txt unterschiedlich gesetzt ist, sollte nur eine der beiden Domains in den Index aufgenommen werden.

Warum dieser Test? Ein Bekannter hat mal beobachtet, wie seine Site trotz robots.txt im Google Index gelandet ist. Hiermit wollen wir jetzt prüfen, ob dies an Fehlern in der robots.txt lag oder ob sich nicht alle Crawler an den Robots Exclusion Standard halten. Dieser ist nur eine Empfehlung.


Ergebnisse

Wie den Screenshots zu entnehmen ist, wurden beide URLs in den Google-Suchindex aufgenommen. Auch wenn bei der Disallow-Variante zwar keine weiteren Informationen ausgewertet wurden, so ist die URL doch im Index. Will man eine Domain also nicht öffentlich sichtbar machen, sollte sie auch nirgendwo verlinkt sein.


Auch eine Suche nach z.B. "robots disallow smiling the sun" liefert dieses Ergebnis - es liegt also nicht daran, dass die genaue URL bekannt ist.


Zu beachten ist, dass dieser Test mit zwei Sub-Domains einer registrierten Domain durchgeführt wurde. Ob dies Einfluss auf die Aufnahme in den Index hat, kann ich nicht sagen.


2010-10-24

"Append JavaScript at the end of my html file" - Component for Tapestry 5.1

This post describes a service, that enables Tapestry to append JavaScript files and script parts at the end of a html file. Script files and scripts can be "dropped into the service" from any page class or component and will be rendered in that order (FIFO) at the end of the page.

Upgrade Tapestry 5.0.x to Tapestry 5.1. loads included JavaScript files in the HTML head. Reasons are discussed in the Upgrade Notes: http://tapestry.apache.org/tapestry5.1/upgrade.html
project-wide release notes. They told me that in fix for bug TAP5-544:
Firstly, JavaScript libraries would have to move (back) to the head, permanently, no configuration [...].
Maybe I did not understand the real concern, but: Why isn't it up to the developer to decide where to place script files?
I decided to write a component that appends my script files at the end of my html files. The most important reason for this descicion is, that--following Yahoo's performance guidelines--I'd like to first load my HTML DOM before loading the script files.

Write a Service to Collect Files to Append
We need an Interface to be able to use the perthread scope (more about scoypes: "a per-thread instance is created on demand, behind a shared proxy").
The Interface just consists of 4 methods. 2 to add Script files and Scripts to the list and 2 to get the lists when they should be rendered:

public interface IAppendedScriptsService {

    /**
     * Add a script file to the list of script files to append.
     *
     * @param scriptFile
     */
    public void addScriptFile(String scriptFile);

    /**
     * Add a script to the list of scripts to append.
     *
     * @param script
     */
    public void addScript(String script);

    /**
     * Returns a list with script files to append. Needs to be a list to preserve order of script files.
     *
     * @return list with script files to append.
     */
    public List
getScriptFiles();

    /**
     * Returns a list with scripts to append. Needs to be a list to preserve order of scripts.
     *
     * @return list with scripts to append.
     */
    public List
getScripts();
}

The implementation of the Interface could looks like the following block. Don't forget to set the scope to perthread.

@Scope(value = ScopeConstants.PERTHREAD)
public class AppendedScriptsService implements IAppendedScriptsService {

    private final List
scriptFiles = new ArrayList();
    private final List
scripts = new ArrayList();

    @Override
    public void addScriptFile(String scriptFile) {
        this.scriptFiles.add(scriptFile);
    }

    @Override
    public void addScript(String script) {
        this.scripts.add(script);
    }

    @Override
    public List
getScriptFiles() {
        return this.scriptFiles;
    }

    @Override
    public List
getScripts() {
        return this.scripts;
    }

}

Build the Component
The Component was easy to write. It consists of just one method to render the scripts:
    // Inject the service we just wrote.
    @Inject
    private IAppendedScriptsService appendedScriptsService;


    // This method is called when component should be rendered. (Markup writer infos)
    void beginRender(MarkupWriter markupWriter) {


        // Output script files.
        if (!this.appendedScriptsService.getScriptFiles().isEmpty()) {
            for (final String file : this.appendedScriptsService.getScriptFiles()) {
                // There might be another (tapestry conform way) to create the source link. My way is
                String fileUrl = "MyAssetsServerURL".resolveRelative(file);
                markupWriter.element("script", "type", "text/javascript", "src", fileUrl);
                markupWriter.end();
            }
        }


        // Output script snippets.
        if (!this.appendedScriptsService.getScripts().isEmpty()) {
            for (final String script : this.appendedScriptsService.getScripts()) {
                markupWriter.element("script", "type", "text/javascript");
                markupWriter.getElement().text(script);
                markupWriter.end();
            }
        }


    }

That's all to implement. Just one last step to make this run:

Activate Service in AppModule
To activate your Service, following method must be inserted into AppModule.java (or just insert the binder-line if there is already such a method):
public static void bind(ServiceBinder binder) {
  binder.bind(IAppendedScriptsService.class, AppendedScriptsService.class);
}
User Component
To use this Component, you just have to add this into a class of a page or component: 
@Inject
private IAppendedScriptsService appendedScriptsService;


/**
* Append JavaScripts
**/
void setupRender() {
    this.appendedScriptsService.addScriptFile("UrlToScript");
    appendedScriptsService.addScript("var x = 'cool';");
}
The order of scripts and script files is preserved.

Do you have any comments? Let's discuss this in the Nabble Forum. I posted the Topic: "Append JavaScript at the end of my html file" - Component for Tapestry 5.1
EDIT: Howard Lewis Ship commented in the Nabble Forum:
The correct approach is to modify the DocumentLinker service (which is internal) to place the

2010-10-05

Design for Mobile: What Gestures do People Use?

Luke Wroblewski schreibt in seinem Blog Ideation + Design immer Kurzfassungen von Vorträgen, an denen er teilnimmt.
Relativ aktuell ist eine Stichpunktesammlung 'What Gestures do People Use?' vom Vortrag von Dan Mauney von der 'Design for Mobile'-Konferenz in Chicago IL.

Es geht hierbei um eine Untersuchung, welche Gestiken Nutzer bei mobilen Endgeräten verwenden. Die Versuchspersonen wurden beauftragt, verschiedene Operationen durchzuführen und hierbei beobachtet.

Besonders erwähnenswert finde ich folgende drei Punkte:


  • Viele Nutzer haben die gefragten Operationen in einem Menü gesucht, obwohl sie gebeten wurden, die Operationen durch Gestiken auszuführen.
  • Die Wischgestik ('swipe') wurde für diverse Operationen verwendet (löschen, multi-select, ausschneiden, scrolling). Es ist also fraglich, ob man beim Entwerfen einer mobilen Benutzerschnittstelle dieser Gestik eine eindeutige Funktion zuweisen kann.
  • Wenn User nicht genau wussten, wie sie eine Funktion erreichen können, haben sie ein Symbol (zum Beispiel ein Fragezeichen für Hilfe) auf den Screen gemalt. Gute Idee - ich glaube, dass ich da nicht drauf gekommen wäre.

2010-10-04

Tapestry5 in Eclipse

Seit einiger Zeit entwickle ich Tapestry 5 in Eclipse und es ist an der Zeit nach guten Plugins zur Unterstützung zu schauen. Bisher hat es nicht viel gegeben, aber heute starte ich eine neue Recherche.

Basis-Setup:
Borut Bolčina schreibt einen Blog über Tapestry 5. Dort hat er sehr ausführlich beschrieben, wie man das Basis-Setup seiner Entwicklungsumgebung macht.
Dort ist auch die Einrichtung von Eclipse Tidy beschrieben. Eclipse Tidy ist super, um HTML-Dateien zu formatieren, aber mit Tapestry gibt es das Problem, dass man ständig neue Komponenten entwickelt und diese mit t:myComponent in den TMLs referenziert. Jede neue Komponente muss man dann in den Eclipse Tiny-Einstellungen hinzufügen. Das kann - insbesondere bei vielen Entwicklern an einem Projekt - sehr nervig werden. Andererseits: Wenn man es gleich von vornherein durchzieht geht es vielleicht.

Code-Completion:
Einen immensen Umfang an Code-Templates findet man im Tapestry Wiki: Tapestry5HowToEclipseCodeTemplates

Im Wiki findet man auch einen Beitrag über Code-Completion in TMLs. Das ist großartig!

Pugins:
Nun aber endlich zu den Plugins. Bisher habe ich loom-t5 von Chris Scheid und tapestry4e von Juan M. Salamanca gekannt und dabei wird es leider auch bleiben, da ich keine weiteren Plugins gefunden habe. In wie weit sich diese Plugins lohnen, schreibe ich im kommenden Blogpost.


Fazit:
Auch wenn ich leider keine neuen Plugins gefunden habe, welches mir eine Verbindung zwischen den TMLs und den Java-Klassen schafft - so dass zum Beispiel die in einer Klasse eingebundenen Komponenten, Properties, etc. im TML mit Code-Completion verfügbar sind: Es lohnt sich immer mal zu schauen, was es Neues gibt.

2010-08-12

Selenium web application testing system

Selenium is a testing framework for Web Applications. With a Selenium test environment, you can programmatically create tests and run them as often as you need. This will ensure that you do not accidentally destroys any previously developed feature during later on development. 


Last year, I set up such a Selenium test environment at work. During the preparation for installing such an environment for a customer, I created a "have-to-read" documentation. It summarizes important issues for the use of Selenium. It is for developers who want to use a Selenium installation, to write their own tests. The information comes--largely--from the selenium-site http://seleniumhq.org/ and is represented here as a "short documentary"--the essentials at a glance with links to the source Selenium Documentation.


If you want to start with selenium, and the framework is set up already, then check this out. 

Commonly Used Selenium Commands

Selenium Commands

Selenium Server

Selenium Server receives Selenium commands from your test program, interprets them, and reports back to your program the results of running those tests.
The RC server bundles Selenium Core and automatically injects it into the browser. This occurs when your test program opens the browser (using a client library API function). Selenium-Core is a JavaScript program, actually a set of JavaScript functions which interprets and executes Selenese commands using the browser’s built-in JavaScript interpreter.
The Server receives the Selenese commands from your test program using simple HTTP GET/POST requests. This means you can use any programming language that can send HTTP requests to automate Selenium tests on the browser.

Client Libraries

A Selenium client library provides a programming interface (API), i.e., a set of functions, which run Selenium commands from your own program. Within each interface, there is a programming function that supports each Selenese command.
The client library takes a Selenese command and passes it to the Selenium Server for processing a specific action or test against the application under test (AUT). The client library also receives the result of that command and passes it back to your program. Your program can receive the result and store it into a program variable and report it as a success or failure, or possibly take corrective action if it was an unexpected error.

Learning the API

Starting the Browser

$this->setBrowser("*firefox");$this->setBrowserUrl("http://www.google.com/");
This example opens the browser and represents that browser by assigning a “browser instance” to a program variable. This program variable is then used to call methods from the browser. These methods execute the Selenium commands, i.e. like open or type or the verify commands.
parameters
  • host: Specifies the IP address of the computer where the server is located. Usually, this is the same machine as where the client is running, so in this case localhost is passed. In some clients this is an optional parameter.
  • port: Specifies the TCP/IP socket where the server is listening waiting for the client to establish a connection. This also is optional in some client drivers.
  • browser: The browser in which you want to run the tests. This is a required parameter.
  • url: The base url of the application under test. This is required by all the client libs and is integral information for starting up the browser-proxy-AUT communication.

Running Commands

Once you have the browser initialized and assigned to a variable (generally named “selenium”) you can make it run Selenese commands by calling the respective methods from the browser variable. For example, to call the type method of the selenium object:
selenium.type("field-id","string to type")
In the background the browser will actually perform a type operation, essentially identical to a user typing input into the browser, by using the locator and the string you specified during the method call.

Adding Some Spice to Your Tests



Troubleshooting Common Problems






Test Design Considerations

  • verify/assertText is the most specific test.
  • With Xpath and DOM you can locate an object with respect to another object on the page.
  • Locate dynamic ID: You need programming logic like:
String[] checkboxIds = selenium.getAllFields(); 
if (!GenericValidator.isBlankOrNull(checkboxIds[i])) {   
    if (checkboxIds[i].indexOF("addFOrm") > 1) { 
        selenium.click(checkboxIds[i]);   
    } 
} 
  • Waiting for AJAX Element:
// Loop 
initialization.for (int second = 0;; second++) {    

    // If loop is reached 60 seconds then break the loop.     
    if (second >= 60) break;     

    // Search for element "link=ajaxLink" and if available then break loop.        try { 
        if (selenium.isElementPresent("link=ajaxLink")) break; 
    } catch (Exception e) {
        // log
    } 

    // Pause for 1 second.
    Thread.sleep(1000); 
} 
This certainly isn’t the only solution. AJAX is a common topic in the user group and we suggest searching previous discussions to see what others have done along with the questions they have posted.
  • UI Mapping: What makes a UI map heplful? Its primary purpose for making test script management much easier. When a locator needs to be edited, there is a central location for easily finding that object.
public void testNew() throws Exception {      
    selenium.open("http://www.test.com");         
    selenium.type(admin.username, "xxxxxxxx");         
    selenium.click(admin.loginbutton);         
    selenium.click(admin.events.createnewevent);         
    selenium.waitForPageToLoad("30000");          
    selenium.click(admin.events.cancel);       
    selenium.waitForPageToLoad("30000");         
    selenium.click(admin.events.viewoldevents);      
    selenium.waitForPageToLoad("30000");
} 
    
admin.username = loginForm:tbUsername; 
admin.loginbutton = loginForm:btnLogin; 
admin.events.createnewevent = adminHomeForm:_activitynew; 
admin.events.cancel = addEditEventForm:_IDcancel; 
admin.events.viewoldevents = adminHomeForm:_activityold; 
  • Data Driven Testing: Refer to the RC wiki for examples of reading data from spread sheet or using data provider capabilities of TestNG with java client driver.

2009-06-30

Google's OpenSocial

OpenSocial ist eine Menge von Programmierschnittstellen für Anwendungen in webbasierten sozialen Netzwerken. OpenSocial wird von Google entwickelt und wurde am 1. November 2007 veröffentlicht. (Quelle: Wikipedia-OpenSocial)
Stichworte zum Bauen von Social Applications
  • Gadgets bestehen hauptsächlich aus HTML und JavaScript.
  • API Namensräume (Javascript) sind opensocial.* und gadgets.*
  • Als Views gibt es in der Klasse gadgets.views.ViewType: Profile View, Canvas View und Home View.
  • Datenhandling/Persistenz findet über opensocial.DataRequest statt. Hierzu zählt auch der Zugriff auf Personen, Beziehungen, Aktivitäten und Nachrichten.
  • Der soziale Graph ist über opensocial.Person erreichbar. Rollen werden in VIEWER und OWNER unterschieden.
  • Aktivitäten: opensocial.Activity. Activity Templates können hierbei häufige Updates kumulieren.
  • Nachrichtenversand: opensocial.Message
  • Internationalisierung über Message Bundles in der XML-Spezifikation des Gadgets möglich.
  • Backend Requests, die über die Möglichkeiten von JavaScript und HTML hinausgehen sollen, können mit gadgets.io.makeRequest() abgesetzt werden. Somit ist der Transfer von HTML-, XML-, JSON- und ATOM-Files möglich. -> JSON, XML und AtomPub können auch über die RESTful API genutzt werden, die neben der JavaScript API existiert.
Quelle: OpenSocial Artikel von Matthias Häsel und Karsten Rieke - http://www.springerlink.com/content/d7624423x371w5v6/

Weitere Infos
Host OpenSocial Apps basierend auf Java oder PHP: Apache Shindig
Let's get this Shindig started


XING und OpenSocial:
XING and OpenSocial


Reblog this post [with Zemanta]

2009-06-16

Thomas Reppa: PureMVC - Introduction + Best Practise

PureMVCImage via Wikipedia
Flash Camp Berlin 2009
Vortrag von Thomas Reppa: PureMVC - Introduction + Best Practise


PureMVC ist ein leichtgewichtiges Framework um MVC Anwendungen in sehr modularer Weise zu erstellen.

  • PureMVC ist eher ein Regelwerk
  • PureMVC ist sprachenunabhängig (impl. in vielen Sprachen vorhanden)
  • Man programmiert Inseln, die man anschließend zusammenfügt.
  • PureMVC ist Kommunikationsschnittstelle zwischen Views und Models.
  • „Code in the Speed of Thought.“

Meine Gedanken:
PureMVC ist ein vielversprechender Ansatz. Allerdings konnte mich der Vortrag leider noch nicht überzeugen, ob in großen (also richtig großen) Projekten das Problem der verwirrenden Verbindungen zwischen Views und Models hiermit zufriedenstellend gelöst werden kann, da nur kleine Beispiele in dem Rahmen gezeigt werden konnten.

Reblog this post [with Zemanta]

2009-05-27

First Steps With Java on Google App Engine

Image representing Google App Engine as depict...Image via CrunchBase
These are my first steps, creating an Java based App with Google App Engine.

Pre-stuff to get it run first:
  1. I sign up for an App Engine account.

  2. Downloaded the App Engine SDK and installed the Eclipse plugin.

  3. Create a new project as described in the Quick Start Reference.

  4. The Quick reference says for deploying (after you have created an application): "Once you have an application ID, just right-click on your project, and select Google > App Engine Settings... from the context menu. Enter your application ID into the Application ID text box. Click OK."

    • I found it quite hard to find the ID until I realized that it is the name itself found in the "Application" column on my apps listing at http://appengine.google.com/. (This is more clear if you just created your app.) So its "peters-cafe" in my case.

  5. Then just hit the turbine button (Deploy App Engine Project) within eclipse, and here we go...
    ...I thought, but got an error: "Unable to upload app: Error posting to URL: http://appengine.google.com/api/appversion/create?app_id=peters-cafe&version=1&
    400 Bad Request
    Invalid runtime or the current user is not authorized to use it."

    --Hmm

  6. I re-checked the developers settings on the app dashboard, but I still was an active developer :-(

  7. Tried wrong credential infos -> PSW doesn't match. So that must be right.

  8. Found it here in Java FAQ: I'm getting "Invalid runtime specified." when I try to upload.
    Acctually I do not have permission to upload a Java app to my account. That's what they say: "To request permission to upload an app which uses the Java runtime, sign up at the following URL: http://appengine.google.com/promo/java_runtime . For now, access will be limited to the first 10,000 to sign up."
    -> sTo request permission to upload an app which uses the Java runtime, sign up at the following URL: http://appengine.google.com/promo/java_runtime . For now, access will be limited to the first 10,000 to sign up.
    -> so nothing to do here, but wait...
In the meantime: Develop Your Application
It is possible, to run the app local, of course, so I will start to develop and test my app locally.
My first steps, developing a Java application with Google App Engine will be reported soon.



Edit Post:

Finally
I got my permission to upload, so here we go: http://peters-cafe.appspot.com/
(Just the default app, currently)


Reblog this post [with Zemanta]

2009-05-10

Was mir neu war über JavaScript (bzw. was ich wieder vergessen hatte)

Beim Lesen des lesenswerten Buches "Das Beste an JavaScript" von O'Reilly und Yahoo!Press habe ich folgende Notizen zusammengestellt. Sie bieten einen guten Überblick über die Aspekte von JavaScript, die über Syntax-Fragen hinaus gehen
  • Vererbung über Prototypen (keine Klassen)
  • Prototyp-Verknüpfungen ermöglichen Vererbung. Dies kann Objekt-Initialisierungen und Speicherverbrauch reduzieren.
  • Objekte werden per Referenz übergeben und nicht als Kopie
  • Delegation über Prototyp-Ketten Object.prototype
  • Um zu verhindern, dass man (zB bei for..in) auch Funktionen in die Hand bekommt, sollte mit hasOwnProperty und typeof gefilter werden.
  • Die Funktions-Aufrufmuster bestimmen, wie der Parameter this initialisiert wird. Es gibt: Methoden-Aufrufmuster, Funktions-Aufrufmuster, Konstruktor-Aufrufmuster und Apply-Aufrufmuster.
  • Anzahl der Aufrufparameter einer Funktion wird nicht zur Laufzeit geprüft. Zu viele Parameter werden abgeschnitten, zu wenige, werden mit undefined gefüllt.
  • Muster:
    • Methode: Funktion als Eigenschaft eines Objekts. this wird an das Objekt gebunden.
    • Funktion: Funktion ist keine Eigenschaft eines Objekts. this wird an das globale Objekt gebunden (Fehler im Design der Sprache!) -> Methode kann innere Funktion nicht nutzen. Workaround: Methode definiert Variable that und weist ihr den Wert von this zu.
    • Konstruktor: (in Variablen mit Großbuchstaben) Funktionsaufruf mit new erzeugt ein neues Objekt und bindet this an das neue Objekt. (Konstruktoren NIE ohne new aufrufen!)
    • Apply: Wert von this wählbar, Array von Argumenten.
  • Eine funktion gibt immer einen Wert zurück. Ohne return-Wert wird undefined zurückgegeben.
  • Einer throw-Anweisung wird ein exception-Objekt übergeben, welches mindestens eine name- und eine message-Eigenschaft besitzt.
  • Hinzufügen einer Methode zu Object.prototype, macht diese für alle Objekte verfügbar (auch wenn diese schon erzeugt wurden).
  • Tail Recursion wird von JavaScript momentan nicht unterstützt.
  • Variablen besitzten keinen Block- sondern einen Funktions-Geltungsbereich. -> Variablen zu Beginn der Funktion deklarieren und nicht erst vor der Verwendung (am besten alle nach EINEM var). -> Zugriff auf Variablen außerhalb der Funktion möglich (außer this und arguments).
  • Kombination von Closures und Funktionen heißen Module. (Javascript Best Practices Folie 30). Dies ist der Begriff für die Technik, um so etwas wie Namespaces für Variablen abbilden zu können. Bei Closures wird einem Objekt keine Funktion zugewiesen, sondern das Ergebnis des Aufrufs dieser Funktion.
  • Callbacks damit der Client nicht steht, bis das Ergebnis kommt.
  • Kaskaden verwenden, indem eine Methode this zurückliefert.
  • Curry
  • Memoization: Bereits in Methoden berechnete Werte "merken". Diese Werte können in ein in einem Closure versteckten Array gespeichert werden.
Darüber hinaus gibt es:
  • Array-Methoden
  • Function-Methoden
  • Number-Methoden
  • Object-Methoden
  • RegEx-Methoden
  • String-Methoden
Da Funktionen Werte sind, zum Verständnis immer besser: var foo = function foo() {};


So, das reicht erst mal. Wenn ich das nächste Mal an JavaScript sitze, werde ich bestimmt wieder etwas hinzufügen können.