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-each-in
The for-each-in loop iterates over the
values in an array:
for each (var elem in 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 = [chk.value for each (checkbox in getCheckboxes())
if (chk.checked)]
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
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;