JavaScript Code Completion mit JSDoc

JavaScript ist ein perfektes Beispiel dafür, wie eine einst verrufene Skriptsprache immer mehr an Zuspruch gewinnen kann. Während man 1997 noch weitläufig dazu geraten hat, JavaScript im Webbrowser zu deaktivieren, so ist man 17 Jahre später anderer Meinung. Mittlerweile können mit JavaScript sogar Mac-OS-Programmabläufe automatisiert werden (siehe JavaScript for Automation) oder native Anwendungen für die Windows-Runtime geschrieben werden. Mit Chrome OS stellt Google sogar ein ganzes Betriebssystem auf den Markt, welches fest auf die Applikationsentwicklung mit JavaScript ausgerichtet ist.

Der aktuelle JavaScript-Trend macht sich auch in den IDEs bemerkbar. JavaScript ist nämlich im Gegensatz zu objektorientierten Programmiersprachen wie Java oder C# nicht typsicher. Die fehlende Typsicherheit in JavaScript macht die Programmiersprache zwar dynamischer aber zugleich auch anfälliger für Programmierfehler. Um der Fehleranfälligkeit vorzubeugen, gibt es bereits in einigen IDEs verschiedene Lösungswege. In Visual Studio wird beispielsweise JavaScript-Code während der Programmierung im Hintergrund ausgeführt, um durch IntelliSense eine sehr genaue Code-Vervollständigung anbieten zu können. Andere IDEs, wie beispielsweise IntelliJ IDEA oder NetBeans, machen sich Code-Kommentare zu Nutzen, um Objekte im Rahmen ihrer Verwendung auswerten zu können.

Die Code-Vervollständigung durch Kommentare zeige ich im folgenden Abschnitt.

In Anlehnung an das „Javadoc Tool“ gibt es mit „JSDoc 3“ auch für JavaScript eine Dokumentationsmöglichkeit mit Code-Kommentaren und Annotationen. Die geschriebenen Kommentare werden durch moderne IDEs wie etwa NetBeans 8 eingelesen und helfen der IDE dabei, Vorschläge beim Schreiben von Code (Auto-Completion) zu machen oder Dokumentationen anzuzeigen.

In der Praxis sieht eine JavaScript-Hilfestellung durch die IDE wie folgt aus:

jsdoc-in-netbeans-8

Damit die IDE die Beschreibungen korrekt anzeigen kann, sollte ein gewisser Programmierstil (Coding conventions) eingehalten werden. Für NetBeans 8.0 und IntelliJ IDEA 13.1.2 empfiehlt sich daher die Verwendung von JavaScript-Prototypen und Annotationen nach JSDoc 3.

Ein vollständiges Beispiel:

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Greeter</title>
    <meta charset="UTF-8" />
  </head>
  <body>
    <script src="js/greeter/1.0.0/GreeterConfiguration.js"></script>
    <script src="js/greeter/1.0.0/GreetingError.js"></script>
    <script src="js/greeter/1.0.0/Greeter.js"></script>
    <script>
      var config = new GreeterConfiguration();
      config.firstName = 'Benny';
      config.lastName = 'Neugebauer';
 
      var greeter = new Greeter(config);
 
      try {
        var greeting = greeter.getGreeting();
        console.log(greeting);
      } catch (error) {
        if (error instanceof GreetingError) {
          console.warn(error.name + ': ' + error.message);
        }
      }
    </script>
  </body>
</html>

GreeterConfiguration.js

/**
 * Configuration object for a personal greeting from a <tt>Greeter</tt>.
 * 
 * @returns {GreeterConfiguration}
 */
function GreeterConfiguration() {
  /**
   * The first name of a person.
   */
  this.firstName = '';
  /**
   * The last name of a person.
   */
  this.lastName = '';
}

GreetingError.js

/**
 * Error class for displaying greeting errors.
 * 
 * @param   {string} message Message for error description.
 * @returns {GreetingError}
 */
function GreetingError(message) {
  this.message = message;
  this.name = 'GreetingError';
}

Greeter.js

/**
 * An object to create a <b>personal greetings</b>. The object can be 
 * initialized with a first and last name. If no name is set, an empty 
 * string is used.
 * 
 * @param   {GreeterConfiguration} config
 * @returns {Greeter}
 */
function Greeter(config) {
  /**
   * The name of a person consisting of first name and last name.
   */
  this.name = undefined;
 
  try {
    this.name = config.firstName + ' ' + config.lastName;
  }
  catch (error) {
    this.name = '';
  }
}
 
/**
 * Creates a personal greeting.
 * 
 * @returns {string}
 * @throws  {GreetingError} if the name was not set.
 */
Greeter.prototype.getGreeting = function() {
  if (this.name.length === 0) {
    throw new GreetingError('Name has not been set.');
  }
 
  return 'Hello ' + this.name + '!';
};

Weiterführende Links:

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.