This guide presents a syntax comparison between Java (8 minimum) and JavaScript (ES6/ES2015 minimum) / TypeScript.

You'll find other guides and a general explanation here.

Why TypeScript ? As a Java developer, you'll love it, and we explain why here. This guide tells clearly when a feature is TypeScript specific. Eveything else is standard JavaScript.

Data declarations

In JavaScript, variables can be declared globally and values are always mutable. Since ES6, use only the let keyword.

        /* Java */
String myData = "java";
myData = "new"; // Error
        /* JavaScript */
let myData = "js";
myData = "new"; // OK
      

ES6 introduced global constants in JavaScript. Complex values can be used and therefore manipulated.

/* Java */
final String MY_DATA = "java";
/* JavaScript */
const MY_DATA = "js";
const MY_USER = new User(); // OK
MY_USER.name = "New name";
      

Simple data types

In vanilla JavaScript, data types are dynamic (a variable can change its type at any time), and you don't need to specify them (they are automatically detected). TypeScript adds manifest and static types. All numbers share the same type in JavaScript.

/* Java */
boolean userMan = true;
int userAge = 81;
float userAverage = 10.5;
String userName = "Henri Bergson";
/* TypeScript */
let userMan: boolean = true;
let userAge: number = 81;
let userAverage: number = 10.5;
let userName: string = "Henri Bergson";
      

In addition to null, JavaScript has the undefined type, and NaN (Not a Number). They are errors, so do not use them.

String details

You can use either single or doubles quotes for strings. ES6 introduced template literals : new backtick quotes for variable interpolation and allowing line breaks. Avoid classic concatenation in JavaScript, as it's confusing with additions and will lead to type errors.

/* Java */
String userFullName  = 
  userFirstName + " " + userLastName;
/* JavaScript (except type) */
let userFullName: string = 
  `${userFirstName} ${userLastName}`;
      

Also useful to manage simple and double quotes in the same string.

/* JavaScript (except type) */
let HTMLTemplate: string = `<p class="content">I'm Henri !</p>`;
      

Data lists

Size of arrays is always dynamic in JavaScript.

/* Java */
List<String> userBooks = 
  new ArrayList<>();
userBooks.add("Book 1");
userBooks.get(0);
userBooks.size();
/* JavaScript (except type) */
let userBooks: string[] = 
  ["Book 1", "Book 2"];
userBooks.push("Book 3");
userBooks[0];
userBooks.length;
      

Hash maps are called objects in JavaScript, with string keys.

/* Java */
Map<String, String> user = 
  new HashMap<>();
user.put("firstName", "Henri");
user.put("lastName", "Bergson");
user.get("firstName");
/* JavaScript */
let user = {
  firstName: "Henri", 
  lastName: "Bergson"
};
user.firstName;
      

As a JavaScript object is like a literal instance, you can use TypeScript interfaces as its type.

/* TypeScript */
interface User {
  age: number;
  name: { first: string, last: string };
}
  
let user: User = {
  age: 81,
  name: { first: "Henri", last: "Bergson" }
};
      

ES6 introduced new collections : Map, Set, WeakMap, WeakSet. You could also be interested by the Immutable JavaScript library.

Blocks

Same syntax for conditions.

Since ES6, thanks to let, variables are block-scoped.

/* Java */
for (int i = 0; i < 10; i++) {}
/* JavaScript (except types) */
for (var i: number = 0; i < 10; i++) {}
i; // 10, error prone

for (let i: number = 0; i < 10; i++) {}
i; // undefined
      

Iteration is simplified in ES6. Do not indicate the type of value in TypeScript (it's automatically inferred).

/* Java */
for (String value: userBooks) {}
/* JavaScript */
for (let value of userBooks) {}
      

Another option for complex iterations (with values and keys, only for arrays).

/* Java */
for (int i = 0; i < books.size(); i++) {
    books.get(i);
}
/* JavaScript (except types) */
books.foreach(
  function (value: string, index: number) {});
      

Functions

In JavaScript, you can access parent scopes directly.

/* Java */
String myData = "java";
void myMethod() {
  myData; // error
}
/* JavaScript (except types) */
let myData: string = "js";
function myMethod(): void {
  myData; // "js"
}
      

No overloading in JavaScript (a function can only have one definition), and parameters are always optional. ES6 introduced default values. TypeScript allow automatic required arguments without manual checking (one of the only major differences with vanilla JS).

/* Java */
void myMethod(String required) {
  myMethod(required, "default");
}
void myMethod
  (String required, String optional) {}
/* JavaScript  (except types) */
function myMethod
  (required: string, 
    optional: string = "default"): void {}
      

ES6 introduced a shorter anonymous functions syntax, named arrow functions.

/* Java */
numbersList.stream()
  .filter(value -> value > 2);
/* JavaScript (except type) */
numbersList
  .filter((value: number) => value > 2);
      

Built-in methods

Some basic methods. Note that length is a property (not a method) in JavaScript.

/* Java */
myEmail.indexOf("@");
myEmail.replaceAll("(.*)@(.*)", " at ");
myEmail.substring(0, 5);
myEmail.length();
Integer.parseInt("10");
/* JavaScript */
myEmail.strpos("@");
myEmail.replace("@", " at ");
myEmail.substring(0, 5);
myEmail.length;
parseInt("10");
      

When a function seems to be called directly, like parseInt(), it's because the global object is implicit : window.parseInt(). Do use the shorthand, as the global object is not always window.

Classes

ES6 introduced classes syntax, to simplify object oriented programming in JavaScript. Properties are directly created in the constructor. Pre-declared properties and visibility modifiers are missing in ES7 : they may appear in future JavaScript versions, but TypeScript allows them right now.

/* Java */
public class User {
  public String firstName;
  public User(String firstName) {
    this.firstName = firstName;
  }
  public void sayHello() {}
}

User myUser = new User("Henri");
myUser.firstName;
myUser.sayHello();
/* JavaScript + TypeScript */
class User {
  public firstName: string;
  public constructor(firstName: string) {
    this.firstName = firstName;
  }
  public sayHello(): void {}
}

let myUser: User = new User("Henri");
myUser.firstName;
myUser.sayHello();
      

In JavaScript inheritance, parent call is required in the child constructor.

/* Java */
public class Editor extends User {
  public Editor(String firstName) {
    super(firstName);
  }
  public void sayHello() {
    super.sayHello();
  }
}
/* JavaScript (except types) */
class Editor extends User {
  public constructor(firstName: string) {
    super(firstName);
  }
  public sayHello(): void {
    super.sayHello();
  }
}
      

Getters and setters have a special syntax in JavaScript (but you can do classic accessors too). Do not pre-declared the property, it is done internally.

/* Java */
public class User {
  protected String name;
  public String getName() {
    return this.name;
  }
  public void setName(String newName) {
    this.name = newName;
  }
}

User myUser = new User("Henri");
myUser.getName();
myUser.setName("New name");
/* JavaScript (except types) */
class User {
  protected _name: string;
  public get name(): string {
    return this._name;
  }
  public set name(newName: string) {
    this._name = newName;
  }
}

let myUser: User = new User("Henri");
myUser.name;
myUser.name = "New name";
      

Same syntax for static methods in JavaScript.

/* JavaScript (except type) */
class Utilities {
  static filter(): void {}
}

Utilities.filter();
      

TypeScript adds abstract classes and interfaces.

/* Java */
public interface Movable {
  public void move();
}

public class Vehicle implements Movable {
    public void move() {}
}

public abstract class Test {}
/* TypeScript */
interface Movable {
  public move(): void;
}

class Vehicle implements Movable {
    public move(): void {}
}

abstract class Test {}
      

Namespaces

Namespacing is directly managed by the loading system since ES6 : if there is the export keyword or import keyword, then you are not anymore in the global scope. Be careful : .js extension is required in JavaScript imports, but in TypeScript, as you'll need to manage both .ts in development and .js in production, it's better to configure the loader to automatically add the right extension.

/* Java */
// User.java
package accounts;

public class User {}

// script.java
import accounts.User;

User myUser = new User();
/* JavaScript (except type) */
// User.ts


export class User {}

// script.ts
import { User } from "./module";

let myUser: User = new User();