Mascara Try it Download Buy About Documentation Blog

Language features

This is a quick overview of language features supported by Mascara. (It is not intended to be a full reference, refer to the reference part of documentation for this)

Variables and scopes

Mascara enforces block level scoping for variables. It verifies that you don't:
  • Use a variable before it is declared or outside the block where it is declared.
  • Assign to a variable which have not been declared (thereby inadvertedly creating or overriding a global variable)
  • Declare the same variable multiple times
  • Use variables before they have been assigned a value (thereby "leaking" undefined values).
All of the above is allowed in plain JavaScript, which can lead to confusing code and subtle bugs.

Syntax

for-of

The for-of loop iterates over the values in an array:
for each (var elem of elements) {
    alert(elem.value);
}
Compare this with the regular for-in which iterates over the keys (indices) of the array:
for (var ix in elements) {
    var elem = elements[ix];
    alert(elem.value);
}

Trailing comma

Allows a trailing comma in array and object literals
var x = [
     "a",
     "b",
     "c",
     ];
Without this, it is a common annoyance or bug to ommit or duplicate commas when adding, removing or rearranging items.

Multiline strings

Triple-quoting allows a string to span multiple lines:
var msg = """
	Hello,
	'World'
	""";

Multiline regular expressions with whitespace and comments

var ptn = /
	   [a-zA-Z]  # letter
	   \d{2,3}   # 2-3 digits
	/x;
ptn.test("x17");

Named and optional parameters

   function f(a, b=true) {}
   f() -> COMPILE TIME ERROR
   f(true)
   f(true, false)
   f(a=false, b=true)
   f(b=false, a=true)
In plain JavaScript, there is no way of indicating required parameters, so any parameter could be missing in any call.

'Rest' parameter

   function f(a, ...b) {}
   f(true, 1, 2, 3, 4);
With a "rest" parameter (indicated with ...) a function can take an arbitrary number of argumets beyound the required arguments. The rest is collected in an array, eg. b gets the value [1,2,3,4] in the above example.

In plain JavaScript all functions can take an arbitrary number of arguments, and there is no indication if you supply more arguments than expected.

Getter/Setter functions

Getters/Setters are written as functions, but invoked as if they were normal variables or properties:
   function get x(){ return 7; }
   function set y(){ }
   y = x;

Array comprehensions

var values =  [for (checkbox of getCheckboxes()) 
            if (chk.checked) chk.value]

Destructuring assignments

Allows you to "unpack" an array or object and assign to multiple variables in one step. Especially useful when returning multiple values from a function.
var [a,b] = [1,2];
var [all, host, tdl] = /$http\:(\w+)\.(\w+)/.exec(url);

Const

A const declaration guarantees that a variable cannot be changed later:
const PI = 4;

Classes

In addition to prototypal inheritance, Mascara supports class-based objects:
	class Car implements Runnable {
	    wheels = 4;
	    run(){...}
	}
	class Volvo extends Car {
		... super() ...
	}
Constructors, static members, overriding methods, private/protected/public attributes and interfaces are supported like in traditional object oriented languages.

Type analysis and verifications

Variables can have (optional) type annotations:
var x : string = "Hello";

Type inference means that you can get type safety with the minimal amount of type annotations.

Parameterized types ("Generics")

var x = new Array.<int>();
x[17] = false // type error!

Structural types

Structural types are described through a set of properties rather than by a class name. Structural types makes it easier to integrate with plain JavaScript, and elevate existing code to type safe code, without having to rewrite everything to use classes.
   function paint(point : {x:int, y:int}) { ... }

type Point = {x:int, y:int} function paint(point : Point) { ... }

Object literals / Prototype objects

The type system recognizes traditional JavaScript object created using object literals and prototypes (with certain limitations due to the halting problem).
   function Car(){}
   Car.prototype = {
      getSpeed: function(){}
   }
   var y = new Car()
   var x = 

Nullability

The dreaded 'null'-errors can be avoided by non-nullabe type annotations, guaranteeing that a variable will never have a null or undefined value:
    var x : !Date = new Date();
    x = null; // ERROR!