JavaScript for Java Programmers

The JavaScript programming language is an OOL that is understood by modern browsers. When a JavaScript program is incorporated into a web page, it provides access to the Document Object Model (DOM) and CSS, allowing the web page to be modified dynamically in response to user actions. It is the "only game in town" for client-side dynamic web pages that work on different browsers.

JavaScript is also known as EcmaScript, the name given to by the European Computer Manufacturers Association (ECMA). The ECMA organization defines the standard for JavaScript. They have substantially improved the language in the past 10-15 years.

In non-object-oriented aspects JavaScript can be described as an untyped version of Java. This implies that Java programmers can learn to write JavaScript code quickly by recognizing the similarities and focusing learning on the differences.

Although HTML provides <a> tags for linking to other web pages, when the user clicks on these tags the browser leaves the current page and goes to the "href" URL specified in the <a> tag. But sometimes you want to bring content into the current web page instead of replacing it. That can be accomplished using the built-in JavaScript XMLHttpRequest class.

One powerful new feature of JavaScript is the ability to define classes that extend the DOM class HTMLElement. The extensions can be used to define new HTML tags. This allows you to define reusable HTML components that can be used in your web pages.

Similarities

The similarities between JavaScript and Java indicate elements of JavaScript that a Java programmer is already familiar with. These include comments, literals, identifiers, operators, and control statements. Although JavaScript's handling of these language elements is not identical to Java's, it is upward compatible: things that work in Java work in JavaScript.

Recommendations

Where JavaScript syntax rules allow you more freedom than Java rules, I recommend sticking with the Java rules. Otherwise you will just have more problems when you go back to programming in Java.

I especially recommend using semicolons even when they are not needed. First of all, the rules for when you don't need them are complicated. You have more important things to think about. Second, you get more precise error messages from the interpreter if you include semicolons. Otherwise the interpreter may have to guess what you intended.

However, beware that allowing you to omit semicolons lead to a few strange syntactic requirements. They are captured in the following recommendations are from ECMAScript® Language Specification

The resulting practical advice to ECMAScript programmers is:
A postfix ++ or -- operator should appear on the same line as its operand.
An Expression in a return or throw statement should start on the same line as the return or throw token.
An Identifier in a break or continue statement should be on the same line as the break or continue token.

Differences

JavaScript differs from Java in its execution model, in its treatment of variables and functions, and in various aspects of its object model.

Execution

An HTML web page can include JavaScript code with a <script> tag. This tag can contain JavaScript code directly or it can reference JavaScript code in an external file. A JavaScript <script> tag should be placed inside the <head> tag.

If the JavaScript code is in embedded directly then it is included with the tag

        <script>
          JavaScript code
        </script>
      

If the JavaScript code is in an external file then it is included with the tag

        <script src="url"/>
      

where url is the url of the JavaScript file. Multiple JavaScript files can be included in this way.

In either case, the JavaScript code should contain a sequence of variable and function definitions. The code should assign a function to the variable window.onload. This function will be executed when the web page has completed loading.

Variables

All JavaScript variables are untyped and they do not need to be declared. JavaScript has two kinds of variables:

There is always an variable named window. It is the global object. Its instance variables can be accessed by name without the window. qualifier.

Inside a function, the function parameters are local variables. Other local variables in a function can be declared with the keyword var:

var name = value-expression;

Beware: all variables other than parameters and variables declared with the keyword var are global variables. They are instance variables of the window object.

Messages

JavaScript messages have one of two forms.

Although this is similar to Java, there is an important difference with regard to methods. JavaScript has a concept of a function that allows functions to exist on their own without being attached to other objects. A function becomes a method of an object when it is assigned to a variable of the object.

JavaScript also differs from Java with regard to default receivers. In the two message forms above, if the receiver is omitted then the implied receiver is the window object. The window object is, in effect, global. There are no other implicit receivers, even inside code for a class!

Functions

JavaScript has a literal notation for functions:

      function(parameter-list) {
        statements
      }
      

Here, parameter-list is a possibly empty, comma-separated list of parameter names. It is similar to the parameter list in a Java method declaration except that the parameters are not typed. As in Java, the parameter names are automatically local to the function.

Function objects can be defined anywhere, even inside another function. They can be used like any other object: they can be assigned to variables and passed as parameters.

They can even have their own instance variables and methods! This allows a function to serve as the constructor method for a class of objects.

The example below assigns a function to a local variable named product.

      var product = function(x, y) {
        return x*y
      };
      

This is equivalent to the more usual function definition below.

      function product(x, y) {
        return x*y
      }
      

Local variables in a function can be declared with the keyword var:

        var name = value;
      

The keyword var is not required here - JavaScript variables do not need to be declared. However, if the keyword var is omitted the variable is global! . This can produce errors that are very hard to debug.

A JavaScript function is potentially an object method. It becomes an object method when it is assigned as the value of one of the object's variables. When JavaScript functions are used as methods, they often need to refer to the receiver object of a message. The keyword this serves this purpose. It is the only way of referring to the receiver.

Objects

In JavaScript, everything is an object (or can be treated like an object). For example, functions are objects.

JavaScript uses functions to serve as classes for constructing multiple objects with similar functionality. JavaScript also has an object literal syntax for creating singleton objects.

Classes

A class of objects is defined by defining a variable whose value is the constructor function for the class, and following it with definitions for static and instance members. Static members have the following form.

      ClassName.memberName = value;
      

Instance members have the following form.

      ClassName.prototype.memberName = value;
      

As usual, the value can be a function literal to produce either static or instance methods.

The Circle class is an example of this kind of construction.

The Circle Class

The comments indicate the form of messages sent to the Circle class object or one of its instances.

Note that if code in an instance method sends a message to the instance, the receiver is specified with the keyword this. JavaScript does not make this the default receiver. Omitting the keyword this results in sending the message to the global window object!

Object Literals

A singleton literal object can be created with a comma-separated list of member definitions enclosed in braces. Each member definition has the following form.

name: value

Both instance variables and methods can be defined in this way. For methods, the value is often an anonymous function definition, but can also refer to a previously defined function.

Thus the general form of a literal object is the following.

      {
        name1: value-expression1,
        .
        .
        .
        namen: value-expressionn
      }
      

As with functions, a literal object can be defined anywhere. It is often assigned to a global variable. When this is done, the object can be used like a Java class whose members are all static. The members are accessed by sending a message with the variable as a receiver. The Log object is an example of this kind of construction. The comments indicate the form of messages sent to the Log object.

The Log Object

In this example, the comments indicate the form of messages sent to the Log object.

Note again that if code in an instance method sends a message to the instance, the receiver is specified with the keyword this. JavaScript does not make this the default receiver. Omitting the keyword this results in sending the message to the global window object!

Encapsulation

JavaScript does encapsulate object data along with methods to manipulate the data. It has recently added the access restriction keyword private.

Polymorphism

JavaScript, like Java, has nonparametric polymorphism - the code executed for a method name depends on the receiver of a message but not on the parameters.

Dispatch in JavaScript is table based for both variables and methods. A JavaScript object structure is a lookup table keyed by variable or method name.

Inheritance

Like Java, JavaScript allows one class to extend another using the extends keyword.

class B extends A {
  // Declarations extending the declarations of class A.
}
      

JavaScript dispatch uses a fully table-based lookup mechanism. This allows JavaScript objects to get new methods at any time - they can be "educated".

Gotchas, Chainsaws, Owies, and Blessings

Some formal definitions:

The most common JavaScript gotcha arises from its handling of default message receivers. A Java programmer typically writes code in a class that sends some messages without mentioning a receiver. For example, when you invoke private instance methods you usually do not mention the default receiver this. In JavaScript, if you do not specify a receiver then you are sending the message to the window global object.

Another gotcha arises from variables that are not declared with the var, let, or const keywords. These variables are implicitly a member of the window global object. This is especially troublesome with regard to loop control variables, which often use short names like i. Two loops that have loop control variables named i without a var declaration are using the same global variable.

The most significant chainsaw in JavaScript is the ability to add methods to objects at run time. This is a powerful tool for dealing with data dynamically, but its use requires care and discipline in order to avoid owies.

JavaScript does have one important blessing: it supports the Document Object Model (DOM). This gives you the capability of creating and modifying parts of a web page dynamically in response to user actions.

Part of supporting DOM is the ability to extend the DOM class HTMLElement, which is the parent class for all HTML element tags. Extending this class allows you to define new HTML tags that can be used in your web pages.

Books

David Flanagan, "JavaScript: The Definitive Guide", 6th Edition, O'Reilly, 2011.

Online References

  1. JavaScript [developer.mozilla.org]
  2. JavaScript Tutorial [www.w3schools.com]
  3. ECMAScript Language Specification [Ecma International]