Squish 7.0 ships with several extensions to the JavaScript support. The main ones are described below.
The earlier additional of classes and modules has been documented in a separate article for Squish 6.6 .
New Operators¶
Added new null coalescing operators and others from ECMAScript 2021:
??
, ??=
, &&=
and ||=
.
The ??
operator, for example, provides a shorthand for checking a value for null
or undefined
. Instead of checking a value like this
let result = someFunction();
if (result == null || typeof result == "undefined")
result = "default";
the check can be shortened to:
let result = someFunction() ?? "default";
Sealing and Freezing of Objects¶
Added Object.seal()
and Object.isSealed()
as well as Object.freeze()
and Object.isFrozen()
.
The behavior of Object.preventExtensions()
and
Object.isExtendible()
got adapted to ECMAScript 2015. Both functions will not
throw an error on non-object type arguments anymore.
The difference between these three concepts is not easy to understand. A brief summary:
- preventExtension: no new properties can be added
- seal: no new properties, no re-configuration of existing properties. Whereas re-configuration means deletion or replacement of/with getter and setter functions.
- freeze: no addition of properties and no change to existing properties whatsoever.
Module exports¶
Previously, the only way to export classes from a module involved a two-step approach: the declaration class C { ... }
and a separate export { C }
declaration. The following shortcut notation is possible now:
export class C {
// ...
};
In addition, a 'deferred' default export can be achieved with the following syntax now: First, declare the entry:
class C {
// ...
}
Then, export the entry with the magic default
name:
export { x as default };
New Object Literals¶
Added additional types of object literal have been added. Next to {a: b, c: d}
that is: {x}
, {a: b,}
, {[expr]: value]}
, {f() { return 1;}}
, {get x() { })
and {set x(v) { }}
. Some examples are
listed below.
Expand an identifier and its associated value:
let one = 1;
let unity = { one }; // { one: 1 }
A property's identifier can be specified by an arbitrary expression when surrounded by square brackets:
let msg = { [uk ? "colour" : "color"] : "red" };
Shorthand for a function definition without usage of the function
keyword:
let cm = { factor: 100, fromMeters(m) { return m * 100; }}
cm.fromMeters(2); // 200
Shorthands for getter and setter functions:
let distance = { l: 0,
get length() { return this.l },
set length(v) { this.l = v < 0 ? -v : v }};
distance.length = -10;
test.log(distance.length); // prints 10
Spread Operator¶
Support the spread operator for function call arguments: (foo(...args))
, array literals [...e]
and object literals {...x}
. The new ...
operator expands any iterable object (like an array) into list that will be passed as e.g. function arguments. Example:
function sum(a, b, c) {
return a + b + c;
}
let x = [1, 2, 3];
test.log(...x); // will print 6
Arrays can be constructed from other arrays like this:
let d2 = [10, 20];
let d3 = [..d2, 30]; // expanded to [10, 20, 30]
Spreading is not limited to arrays. Any object with iterable items work. Like a string:
let chars = [..."red"]; // expanded to ["r", "e", "d"]
Object literals can make use of the operator as well:
let a = { x: 1, y: 2};
let b = { ...a, z: 3}; // expanded to { x: 1, y: 2, z: 3 }
Bugfix¶
Fixed this
value in function called via a super
reference. It
pointed to a wrong object before.
Note on IDE Support¶
Some of the recently added features go beyond what the 3rd party JavaScript editor from Eclipse is able to support. Script code that will work fine in SquishRunner may have incomplete syntax highlighting or code completion in the IDE. We are investigating a replacement of the editor with completely different implementation.