- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
12-19-2022 07:23 AM - edited 12-19-2022 09:12 AM
This article describes JavaScript engine feature support: Newly available in ES 12. I have combined several sources to create this article. Please refer to the list of resources at the bottom of the page to find out more.
Overview
This article will cover all Supported ES12 features that were not supported in the ES5 standard before. You can find a complete list, including Disallowed or Not Supported features here.
Newly supported in Tokyo release (scoped app)
The features that are supported are the following. Below the list more details are provided, including examples.
ECMAScript 12 features
- Logical assignment
- Numeric separators
ECMAScript 11 features
- String.prototype.matchAll
- Optional chaining operator (?.)
- Promise.allSettled
ECMAScript 10 features
- Symbol.prototype.description
- String trimming
- Array.prototype.{flat, flatMap}
- Object.fromEntries
ECMAScript 9 features
- Object rest/spread properties
ECMAScript 8 features
- Object static methods
- String padding
- Trailing commas in function syntax
ECMAScript 7 features
- Exponentiation (**) operator
- Array.prototype.includes
ECMAScript 6 features
- Default function parameters
- Rest parameters
- Spread syntax for iterable objects
- Object literal extensions
- For-of loops
- Octal and binary literals
- Template literals
- RegExp "y" and "u" flags
- Destructuring, declarations
- Destructuring, assignment
- Destructuring, parameters
- Unicode code point escapes
- Const
- Let
- Block-level function declaration
- Arrow functions
- Class
- Super
- Map
- Set
- Symbol
- Object static methods
- Function "name" property
- String static methods
- String.prototype methods
- RegExp.prototype properties
- Array static methods
- Array.prototype methods
- Number properties
- Math methods
- Date.prototype[Symbol.toPrimitive]
ECMAScript 5 features
- String properties and methods
ECMAScript 12 features
Logical assignment
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
---|---|---|
||= basic support |
Supported |
Not Supported |
||= short-circuiting behavior |
Supported |
Not Supported |
||= setter not unnecessarily invoked |
Supported |
Not Supported |
&&= basic support |
Supported |
Not Supported |
&&= short-circuiting behavior |
Supported |
Not Supported |
&&= setter not unnecessarily invoked |
Supported |
Not Supported |
??= basic support |
Supported |
Not Supported |
??= short-circuiting behavior |
Supported |
Not Supported |
??= setter not unnecessarily invoked |
Supported |
Not Supported |
||= (OR-EQUAL) operator
The OR-EQUAL operator is used to assign a value to a variable if the variable is null or undefined. If the variable has a value, it will not be overwritten. Here is an example of how it can be used in ServiceNow:
(function executeRule(current, previous /*null when async*/) {
var gr = new GlideRecord('incident');
gr.get('INC0000002');
// If the 'priority' field is null or undefined, assign it a value of '1 - Critical'
gr.priority ||= '1 - Critical';
// If the 'urgency' field is null or undefined, assign it a value of '1 - High'
gr.urgency ||= '1 - High';
gr.update();
})(current, previous);
&&= (AND-EQUAL) operator
The AND-EQUAL operator is used to assign a value to a variable if the variable has a truthy value. If the variable has a falsy value (null, undefined, 0, "", etc.), it will not be overwritten. Here is an example of how it can be used in ServiceNow:
(function executeRule(current, previous /*null when async*/) {
var gr = new GlideRecord('incident');
gr.get('INC0000002');
// If the 'priority' field has a truthy value, assign it a value of '1 - Critical'
gr.priority &&= '1 - Critical';
// If the 'urgency' field has a truthy value, assign it a value of '1 - High'
gr.urgency &&= '1 - High';
gr.update();
})(current, previous);
??= (NULLISH-COALESCING-EQUAL) operator
The NULLISH-COALESCING-EQUAL operator is similar to the OR-EQUAL operator, but it only assigns a value to a variable if the variable is null or undefined. It does not overwrite the value if it is a falsy value (0, "", etc.). Here is an example of how it can be used in ServiceNow:
(function executeRule(current, previous /*null when async*/) {
var gr = new GlideRecord('incident');
gr.get('INC0000002');
// If the 'priority' field is null or undefined, assign it a value of '1 - Critical'
gr.priority ??= '1 - Critical';
// If the 'urgency' field is null or undefined, assign it a value of '1 - High'
gr.urgency ??= '1 - High';
gr.update();
})(current, previous);
Numeric separators
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
numeric separators |
Supported |
Not Supported |
(function executeRule(current, previous /*null when async*/) {
var gr = new GlideRecord('incident');
gr.get('INC0000002');
// Use numeric separators to make the large number more readable
gr.number_of_affected_users = 100_000_000;
gr.update();
})(current, previous);
Numeric separators can be used to make large numbers more readable by inserting underscores (_) between groups of digits. The underscores are ignored by the JavaScript interpreter and do not affect the value of the number. In the example above, the number 100_000_000 is interpreted as 100000000.
Numeric separators are particularly useful when working with large numbers that might be difficult to read or understand without them. They can also help to improve the readability and maintainability of your code.
ECMAScript 11 features
String.prototype.matchAll
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic functionality |
Supported |
Not Supported |
throws on non-global regex |
Supported |
Not Supported |
(function executeRule(current, previous /*null when async*/) {
var description = "This is an incident so I created a ticket";
// Use matchAll to find all instances of a pattern in a string
var matches = description.matchAll(/\b(incident|ticket)\b/gi);
// Iterate over the matches and log them to the console
for (const match of matches) {
gs.info(match[0]); //"incident" and "ticket"
}
})(current, previous);
The String.prototype.matchAll function is used to find all instances of a pattern in a string. It returns an iterator that contains the matches as an array of strings. In the example above, the function is used to search the 'short_description' field of a GlideRecord for the words 'incident' or 'ticket', ignoring case. The matches are then logged to the console.
The matchAll function is particularly useful when you want to find multiple instances of a pattern in a string, rather than just the first one. It is also useful when working with global regular expressions, as it allows you to iterate over all the matches rather than just the first one.
Optional chaining operator (?.)
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
optional property access |
Supported |
Not Supported |
optional bracket access |
Supported |
Not Supported |
optional method call |
Supported |
Not Supported |
optional function call |
Supported |
Not Supported |
spread parameters after optional chaining |
Supported |
Not Supported |
var gr = new GlideRecord('incident');
gr.get('INC0000002');
// Use optional chaining to safely access nested object properties
var customerName = gr.caller_id.first_name?.toUpperCase();
// If the caller_id field is null or the first_name property is undefined, customerName will be assigned the value of undefined
if (customerName) {
gr.description = 'Hello, ' + customerName + '! How can we help you today?';
} else {
gr.description = 'We were unable to retrieve the customer name.';
}
gr.update();
The optional chaining operator (?.) allows you to safely access nested object properties by automatically returning undefined if any of the properties in the chain are null or undefined. In the example above, the operator is used to access the 'first_name' property of the 'caller_id' field of the GlideRecord. If the 'caller_id' field is null or the 'first_name' property is undefined, the value of customerName will be undefined.
Promise.allSettled
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
nullish coalescing operator (??) |
Supported |
Not Supported |
ECMAScript 10 features
Symbol.prototype.description
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic |
Supported |
Not Supported |
empty description |
Supported |
Not Supported |
undefined description |
Supported |
Not Supported |
var incidentType = Symbol('incident type');
// Use Symbol.prototype.description to get the description for the symbol
var description = incidentType.description;
// The value of description will be 'incident type'
gs.info(description);
The Symbol.prototype.description function returns the description for a symbol. In the example above, the function is used to get the description for the 'incidentType' symbol, which was created with a description of 'incident type'. The value of 'description' will be 'incident type'.
String trimming
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
String.prototype.trimLeft |
Supported |
Supported |
String.prototype.trimRight |
Supported |
Supported |
String.prototype.trimStart |
Supported |
Not Supported |
String.prototype.trimEnd |
Supported |
Not Supported |
The main difference between these methods is the characters that they remove from the beginning and end of a string.
- String.prototype.trimLeft and String.prototype.trimRight remove whitespace characters from the left and right sides of a string, respectively. These methods are equivalent to the older String.prototype.trim method.
- String.prototype.trimStart and String.prototype.trimEnd remove all leading and trailing whitespace and Unicode "space" characters from a string, respectively. These methods are more powerful than String.prototype.trimLeft and String.prototype.trimRight, as they remove all space characters rather than just ASCII whitespace characters.
var description = ' This is a description with leading and trailing whitespace ';
// Use trimStart to remove leading whitespace
var trimmedStart = description.trimStart();
// Use trimEnd to remove trailing whitespace
var trimmedEnd = description.trimEnd();
gs.info(trimmedStart); // 'This is a description with leading and trailing whitespace '
gs.info(trimmedEnd); // ' This is a description with leading and trailing whitespace'
In the example above, the String.prototype.trimStart method is used to remove leading whitespace from the 'description' string, and the String.prototype.trimEnd method is used to remove trailing whitespace. The resulting strings are logged to the console.
Array.prototype.{flat, flatMap}
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Array.prototype.flat |
Supported |
Not Supported |
Array.prototype.flatMap |
Supported |
Not Supported |
flat and flatMap in Array.prototype[@@unscopables] |
Supported |
Not Supported |
Object.fromEntries
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Object.fromEntries |
Supported |
Not Supported |
var entries = [ ['a', 1],
['b', 2],
['c', 3]
];
// Use Object.fromEntries to create an object from the entries array
var obj = Object.fromEntries(entries);
gs.info(JSON.stringify(obj)); // { a: 1, b: 2, c: 3 }
The Object.fromEntries function creates an object from an iterable of key-value pairs. In the example above, the function is used to create an object from the 'entries' array, which contains an iterable of key-value pairs. The resulting object is logged to the console.
ECMAScript 9 features
Object rest/spread properties
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
object rest properties |
Supported |
Not Supported |
object spread properties |
Supported |
Not Supported |
var obj = {
a: 1,
b: 2,
c: 3
};
// Use the spread operator (...) to create a new object with the properties of obj
var newObj = { ...obj };
gs.info(JSON.stringify(newObj)); // { a: 1, b: 2, c: 3 }
// Use the rest operator (...) to create a new object with all properties except 'a'
var { a, ...rest } = obj;
gs.info(JSON.stringify(rest)); // { b: 2, c: 3 }
The spread operator (...) allows you to expand an iterable (such as an array or object) into individual elements or properties. The rest operator (...) allows you to gather a set of individual elements or properties into a new object.
In the example above, the spread operator is used to create a new object with the properties of the 'obj' object, and the rest operator is used to create a new object with all properties of 'obj' except 'a'. The resulting objects are logged to the console.
ECMAScript 8 features
Object static methods
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Object.values |
Supported |
Not Supported |
Object.entries |
Supported |
Not Supported |
Object.getOwnPropertyDescriptors |
Supported |
Not Supported |
var obj = {
a: 1,
b: 2,
c: 3
};
// Use Object.values to get an array of the object's values
var values = Object.values(obj);
gs.info(values); // [ 1, 2, 3 ]
// Use Object.entries to get an array of the object's key-value pairs
var entries = Object.entries(obj);
gs.info(entries); // [ ['a', 1], ['b', 2], ['c', 3] ]
// Use Object.getOwnPropertyDescriptors to get an object with property descriptor objects for the object's own properties
var descriptors = Object.getOwnPropertyDescriptors(obj);
gs.info(JSON.stringify(descriptors)); // { a: { value: 1, writable: true, enumerable: true, configurable: true }, b: { value: 2, writable: true, enumerable: true, configurable: true }, c: { value: 3, writable: true, enumerable: true, configurable: true } }
The Object.values method returns an array of the values of an object's own enumerable properties. The Object.entries method returns an array of the object's own enumerable property [key, value] pairs. The Object.getOwnPropertyDescriptors method returns an object with property descriptor objects for the object's own properties.
In the example above, these methods are used to get the values, key-value pairs, and property descriptor objects of the 'obj' object. The resulting arrays and objects are logged to the console.
String padding
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
String.prototype.padStart |
Supported |
Not Supported |
String.prototype.padEnd |
Supported |
Not Supported |
var str = 'hello';
// Use String.prototype.padStart to pad the string with spaces until it is 10 characters long
var paddedStr = str.padStart(10, ' ');
gs.info(paddedStr); // ' hello'
// Use String.prototype.padEnd to pad the string with spaces until it is 10 characters long
var paddedStr = str.padEnd(10, ' ');
gs.info(paddedStr); // 'hello '
The String.prototype.padStart and String.prototype.padEnd methods allow you to pad a string with a specified string or character until it reaches a certain length. The padStart method adds padding to the beginning of the string, and the padEnd method adds padding to the end of the string.
In the example above, the padStart and padEnd methods are used to add spaces to the 'str' string until it is 10 characters long. The resulting padded strings are logged to the console.
Trailing commas in function syntax
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
in parameter lists |
Supported |
Not Supported |
in argument lists |
Supported |
Not Supported |
A trailing comma in a function's parameter list is a syntax that allows you to include an extra comma after the last parameter in a list of parameters. This can be useful when you need to add or remove parameters from a function, as it allows you to do so without having to update all the subsequent lines of code that call the function.
function greet(name, greeting = 'Hello',) {
gs.info(`${greeting}, ${name}!`);
}
In this example, the function greet() takes two parameters: name and greeting. The greeting parameter has a default value of 'Hello', and there is a trailing comma after it. This means that you can call the function with just the name parameter, like this:
greet('John'); // Outputs: "Hello, John!"
A trailing comma in the argument list works in a similar way. It allows you to include an extra comma after the last argument in a list of arguments when calling a function. This can also be useful when you need to add or remove arguments from a function call, as it allows you to do so without having to update all the subsequent lines of code that use the function.
greet('John', 'Hi',); // Outputs: "Hi, John!"
In this example, the function greet() is called with two arguments: 'John' and 'Hi'. There is a trailing comma after the 'Hi' argument. This allows you to add additional arguments to the function call without having to update all the subsequent lines of code that use the function.
ECMAScript 7 features
Exponentiation (**) operator
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic support |
Supported |
Not Supported |
assignment |
Supported |
Not Supported |
The exponentiation operator (**) is used to calculate the power of a number. It was introduced in ECMAScript 2016 and is a shorthand for the Math.pow() method.
Here's an example of the exponentiation operator in action:
let base = 2;
let exponent = 3;
let result = base ** exponent;
console.log(result); // Outputs: 8
In this example, the variable result is assigned the value of 2 to the power of 3, which is 8.
Array.prototype.includes
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Array.prototype.includes |
Supported |
Not Supported |
The Array.prototype.includes() method is a standard method in JavaScript that determines whether an array includes a certain element, returning a boolean value. It was introduced in ECMAScript 2016 and is an extension of the indexOf() method.
let numbers = [1, 2, 3, 4, 5];
gs.info(numbers.includes(3)); // Outputs: true
gs.info(numbers.includes(6)); // Outputs: false
In this example, the includes() method is used to check if the array numbers includes the value 3. Since the array does include the value 3, the method returns true. When the method is called again to check for the value 6, which is not present in the array, it returns false.
ECMAScript 6 features
Default function parameters
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic functionality |
Supported |
Not Supported |
explicit undefined defers to the default |
Supported |
Not Supported |
defaults can refer to previous parameters |
Supported |
Not Supported |
arguments object interaction |
Supported |
Not Supported |
separate scope |
Supported |
Not Supported |
Default function parameters allow you to specify default values for function parameters in case no value or undefined is passed to the function.
Basic functionality
Here is an example of how default function parameters can be used in a ServiceNow server-side script:
function greet(name = 'John') {
gs.info(`Hello, ${name}!`);
}
greet(); // Outputs: "Hello, John!"
greet('Jane'); // Outputs: "Hello, Jane!"
In the example above, the 'greet' function has a default parameter value of 'John' for the 'name' parameter. If no value is passed to the function when it is called, the default value of 'John' is used. If a value is passed, it is used instead of the default value.
Explicit undefined defers to the default
If the value passed to the function is explicitly set to undefined, the default value will be used:
function greet(name = 'John') {
gs.info(`Hello, ${name}!`);
}
Defaults can refer to previous parameters
Default values for function parameters can refer to previous parameters in the function definition:
function greet(greeting = 'Hello', name = `${greeting}, John!`) {
gs.info(name);
}
greet(); // Outputs: "Hello, John!"
In the example above, the default value for the 'name' parameter is set to a string that includes the value of the 'greeting' parameter.
Arguments object interaction
The arguments object, which is an array-like object that contains the values of the arguments passed to a function, can be used in conjunction with default function parameters:
function greet() {
gs.info(arguments[0]);
// expected output: Hallo
gs.info(arguments[1]);
// expected output: Hi
gs.info(arguments[2]);
// expected output: Hello
}
greet('Hallo', 'Hi', 'Hello');
In the example above, the greet function returns the first argument passed to the function [0], then the second argument [1], and finaly the third [2].
Separate scope
Default function parameters have their own separate scope, which means that variables used in default values are not accessible outside of the function definition:
function greet(name = x) {
gs.info(`Hello, ${name}!`);
}
let x = 'John';
greet(); // Outputs: "Hello, John!"
gs.info(x); // Outputs: "John"
In the example above, the default value for the 'name' parameter is set to the value of the 'x' variable, which is declared outside of the function. However, the 'x' variable is not accessible within the function definition, so it does not affect the value of the 'name' parameter.
Rest parameters
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic functionality |
Supported |
Not Supported |
function 'length' property |
Supported |
Not Supported |
Basic functionality
Rest parameters allow a function to accept any number of arguments as an array. They are denoted by three dots (...) followed by a parameter name.
For example:
function sum(...numbers) {
let total = 0;
for (let number of numbers) {
total += number;
}
return total;
}
gs.info(sum(1, 2, 3)); // Outputs: 6
gs.info(sum(1, 2, 3, 4, 5)); // Outputs: 15
In the example above, the 'sum' function uses a rest parameter called 'numbers' to accept any number of arguments. It then loops through the 'numbers' array and calculates the total sum of all the elements.
function 'length' property
The 'length' property of a function indicates the number of arguments the function expects. For functions with rest parameters, the 'length' property is set to the number of non-rest parameters.
For example:
function sum(x, y, ...numbers) {
let total = 0;
for (let number of numbers) {
total += number;
}
return total + x + y;
}
gs.info(sum.length); // Outputs: 2
In the example above, the 'sum' function has a rest parameter called 'numbers' and two non-rest parameters called 'x' and 'y'. The 'length' property is therefore set to 2, indicating that the function expects two arguments.
Spread syntax for iterable objects
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
with arrays, in function calls |
Supported |
Not Supported |
with arrays, in array literals |
Supported |
Not Supported |
with sparse arrays, in array literals |
Supported |
Not Supported |
with strings, in array literals |
Supported |
Not Supported |
with astral plane strings, in array literals |
Supported |
Not Supported |
with generic iterables, in calls |
Supported |
Not Supported |
with generic iterables, in arrays |
Supported |
Not Supported |
with instances of iterables, in calls |
Supported |
Not Supported |
with instances of iterables, in arrays |
Supported |
Not Supported |
In ServiceNow, the spread syntax allows you to expand an iterable object (such as an array or a string) into individual elements when used in an array literal or function call. This can be a convenient way to pass a group of elements as arguments to a function or to include multiple elements in an array without having to manually list each one.
Here are some examples of using the spread syntax with different types of iterable objects:
With arrays in function calls
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
gs.info(sum(...numbers)); // Output: 6
With arrays in array literals
const numbers1 = [1, 2, 3];
const numbers2 = [4, 5, 6];
const numbers3 = [...numbers1, ...numbers2];
gs.info(numbers3); // Output: [1, 2, 3, 4, 5, 6]
With sparse arrays in array literals
const sparseArray = [1, , , 4];
const denseArray = [...sparseArray];
gs.info(denseArray); // Output: [1, undefined, undefined, 4]
With strings in array literals
const string = "hello";
const characters = [...string];
gs.info(characters); // Output: ['h', 'e', 'l', 'l', 'o']
With astral plane strings in array literals
const astralString = "";
const astralCharacters = [...astralString];
gs.info(astralCharacters); // Output: ['', '', '', '', '']
With generic iterables in function calls
function print(...elements) {
gs.info(elements);
}
const iterable = {
[Symbol.iterator]() {
let i = 0;
return {
next() {
return { value: i++, done: i > 3 };
}
};
}
};
print(...iterable); // Output: [0, 1, 2]
With generic iterables in array literals
const iterable = {
[Symbol.iterator]() {
let i = 0;
return {
next() {
return { value: i++, done: i > 3 };
}
};
}
};
const array = [...iterable];
gs.info(array); // Output: [0, 1, 2]
With instances of iterables in function calls
class MyIterable {
[Symbol.iterator]() {
let i = 0;
return {
next() {
return { value: i++, done: i > 3 };
}
};
}
}
function print(...elements) {
gs.info(elements);
}
const iterable = new MyIterable();
print(...iterable); // Output: [0, 1, 2]
With instances of iterables in array literals
class MyIterable {
[Symbol.iterator]() {
let i = 0;
return {
next() {
return { value: i++, done: i > 3 };
}
};
}
}
const iterable = new MyIterable();
const array = [...iterable];
gs.info(array); // Output: [0, 1, 2]
Object literal extensions
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
computed properties |
Supported |
Not Supported |
shorthand properties |
Supported |
Not Supported |
shorthand methods |
Supported |
Not Supported |
string-keyed shorthand methods |
Supported |
Not Supported |
computed shorthand methods |
Supported |
Not Supported |
computed accessors |
Supported |
Not Supported |
For-of loops
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
with arrays |
Supported |
Not Supported |
with sparse arrays |
Supported |
Not Supported |
with strings |
Supported |
Not Supported |
with astral plane strings |
Supported |
Not Supported |
with generic iterables |
Supported |
Not Supported |
with instances of generic iterables |
Supported |
Not Supported |
iterator closing, break |
Supported |
Not Supported |
iterator closing, throw |
Supported |
Not Supported |
"A different kind of for/in to add to your arsenal." Reference this.
//before
(function executeRule(current, previous /*null when async*/) {
var inc_gr = new GlideRecord('incident');
inc_gr.orderByDesc('number');
inc_gr.setLimit(10);
inc_gr.query();
var incidents = [];
while (inc_gr.next()){
incidents.push(inc_gr.getValue('short_description'));
}
var work_notes = [];
for (var inc in incidents){
work_notes.push(incidents[inc]);
}
current.work_notes = work_notes.join('\n');
})(current, previous);
//after
(function executeRule(current, previous /*null when async*/) {
var inc_gr = new GlideRecord('incident');
inc_gr.orderByDesc('number');
inc_gr.setLimit(10);
inc_gr.query();
var incidents = [];
while (inc_gr.next()){
incidents.push(inc_gr.getValue('short_description'));
}
let work_notes = [];
for (let inc of incidents){
work_notes.push(inc); //note that no index reference is needed
}
current.work_notes = work_notes.join('\n');
})(current, previous);
Octal and binary literals
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
octal literals |
Supported |
Not Supported |
binary literals |
Supported |
Not Supported |
Template literals
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic functionality |
Supported |
Not Supported |
toString conversion |
Supported |
Not Supported |
tagged template literals |
Supported |
Not Supported |
passed array is frozen |
Supported |
Not Supported |
TemplateStrings call site caching |
Supported |
Not Supported |
TemplateStrings permanent caching |
Supported |
Not Supported |
This example is from the developer blog here:
(function executeRule(current, previous /*null when async*/) {
let x = `hello
world
lchh loves you`;
current.work_notes = x; //goodbye \n
})(current, previous);
Alternative by Chris Helming:
(function executeRule(current, previous /*null when async*/) {
const a = 5;
const b = 10;
current.work_notes = `Fifteen is ${a + b} and not ${2 * a + b}.`;
})(current, previous);
RegExp "y" and "u" flags
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
"y" flag |
Supported |
Not Supported |
"y" flag, lastIndex |
Supported |
Not Supported |
Destructuring, declarations
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
with arrays |
Supported |
Not Supported |
with sparse arrays |
Supported |
Not Supported |
with strings |
Supported |
Not Supported |
with astral plane strings |
Supported |
Not Supported |
with generic iterables |
Supported |
Not Supported |
with instances of generic iterables |
Supported |
Not Supported |
iterator closing |
Supported |
Not Supported |
trailing commas in iterable patterns |
Supported |
Not Supported |
with objects |
Supported |
Not Supported |
object destructuring with primitives |
Supported |
Not Supported |
trailing commas in object patterns |
Supported |
Not Supported |
throws on null and undefined |
Supported |
Not Supported |
computed properties |
Supported |
Not Supported |
multiples in a single var statement |
Supported |
Not Supported |
nested |
Supported |
Not Supported |
in for-in loop heads |
Supported |
Not Supported |
in for-of loop heads |
Supported |
Not Supported |
in catch heads |
Supported |
Not Supported |
rest |
Supported |
Not Supported |
defaults |
Supported |
Not Supported |
Destructuring, assignment
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
with arrays |
Supported |
Not Supported |
with sparse arrays |
Supported |
Not Supported |
with strings |
Supported |
Not Supported |
with astral plane strings |
Supported |
Not Supported |
with generic iterables |
Supported |
Not Supported |
with instances of generic iterables |
Supported |
Not Supported |
iterator closing |
Supported |
Not Supported |
iterable destructuring expression |
Supported |
Not Supported |
chained iterable destructuring |
Supported |
Not Supported |
trailing commas in iterable patterns |
Supported |
Not Supported |
with objects |
Supported |
Not Supported |
object destructuring with primitives |
Supported |
Not Supported |
trailing commas in object patterns |
Supported |
Not Supported |
object destructuring expression |
Supported |
Not Supported |
chained object destructuring |
Supported |
Not Supported |
throws on null and undefined |
Supported |
Not Supported |
computed properties |
Supported |
Not Supported |
nested |
Supported |
Not Supported |
rest |
Supported |
Not Supported |
nested rest |
Supported |
Not Supported |
empty patterns |
Supported |
Not Supported |
defaults |
Supported |
Not Supported |
Destructuring, parameters
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
with arrays |
Supported |
Not Supported |
with sparse arrays |
Supported |
Not Supported |
with strings |
Supported |
Not Supported |
with astral plane strings |
Supported |
Not Supported |
with generic iterables |
Supported |
Not Supported |
with instances of generic iterables |
Supported |
Not Supported |
iterator closing |
Supported |
Not Supported |
trailing commas in iterable patterns |
Supported |
Not Supported |
with objects |
Supported |
Not Supported |
object destructuring with primitives |
Supported |
Not Supported |
trailing commas in object patterns |
Supported |
Not Supported |
throws on null and undefined |
Supported |
Not Supported |
computed properties |
Supported |
Not Supported |
nested |
Supported |
Not Supported |
'arguments' interaction |
Supported |
Not Supported |
in parameters, function 'length' property |
Supported |
Not Supported |
rest |
Supported |
Not Supported |
empty patterns |
Supported |
Not Supported |
defaults |
Supported |
Not Supported |
defaults, separate scope |
Supported |
Not Supported |
aliased defaults, arrow function |
Supported |
Not Supported |
shorthand defaults, arrow function |
Supported |
Not Supported |
Unicode code point escapes
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
in strings |
Supported |
Not Supported |
Const
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
is block-scoped |
Supported |
Not Supported |
scope shadow resolution |
Supported |
Not Supported |
for loop statement scope |
Supported |
Not Supported |
for-in loop iteration scope |
Supported |
Not Supported |
for-of loop iteration scope |
Supported |
Not Supported |
basic support (strict mode) |
Supported |
Supported |
is block-scoped (strict mode) |
Supported |
Not Supported |
scope shadow resolution (strict mode) |
Supported |
Not Supported |
for loop statement scope (strict mode) |
Supported |
Not Supported |
for-in loop iteration scope (strict mode) |
Supported |
Not Supported |
for-of loop iteration scope (strict mode) |
Supported |
Not Supported |
"This was actually available previously but would display an error to you when using it, despite allowing you to save. Almost everything else related to ECMAScript 6 and up would not allow you to save your record at all.
const
is a way to declare and initialize a variable that will never change its value. A great way to ensure a variable that is not meant to change never does (your script will throw an error)." Reference this.
(function executeRule(current, previous /*null when async*/) {
var inc_gr = new GlideRecord('incident');
inc_gr.query();
var x = inc_gr.getRowCount();
const y = 100;
current.work_notes = x + y;
})(current, previous);
Let
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic support |
Supported |
Not Supported |
is block-scoped |
Supported |
Not Supported |
scope shadow resolution |
Supported |
Not Supported |
for loop statement scope |
Supported |
Not Supported |
for/for-in loop iteration scope |
Supported |
Not Supported |
basic support (strict mode) |
Supported |
Not Supported |
is block-scoped (strict mode) |
Supported |
Not Supported |
scope shadow resolution (strict mode) |
Supported |
Not Supported |
for loop statement scope (strict mode) |
Supported |
Not Supported |
for/for-in loop iteration scope (strict mode) |
Supported |
Not Supported |
(function executeRule(current, previous /*null when async*/) {
var inc_gr = new GlideRecord('incident');
inc_gr.query();
var x = inc_gr.getRowCount();
let y = 200;
current.work_notes = x + y;
})(current, previous);
Block-level function declaration
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
block-level function declaration |
Supported |
Not Supported |
Arrow functions
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
0 parameters |
Supported |
Not Supported |
1 parameter, no brackets |
Supported |
Not Supported |
multiple parameters |
Supported |
Not Supported |
lexical "this" binding |
Supported |
Not Supported |
"this" unchanged by call or apply |
Supported |
Not Supported |
can't be bound, can be curried |
Supported |
Not Supported |
lexical "arguments" binding |
Supported |
Not Supported |
lexical "super" binding in constructors |
Supported |
Not Supported |
lexical "super" binding in methods |
Supported |
Not Supported |
"Arrow functions are a compact alternative to traditional function expressions. Combined with other new features, there are so many use-cases for arrow functions (like quickly reordering arrays of objects!)". Reference this.
//before
(function executeRule(current, previous /*null when async*/) {
var sd = current.short_description;
var d = current.description;
function addDescriptions(x, y){
return x + '\n' + y;
}
current.work_notes = addDescriptions(sd, d);
})(current, previous);
//after
(function executeRule(current, previous /*null when async*/) {
var sd = current.short_description;
var d = current.description;
let addDescriptions = (x, y) => x + '\n'+ y; //one line!
current.work_notes = addDescriptions(sd, d);
})(current, previous);
Class
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
class statement |
Supported |
Not Supported |
is block-scoped |
Supported |
Not Supported |
class expression |
Supported |
Not Supported |
anonymous class |
Supported |
Not Supported |
constructor |
Supported |
Not Supported |
prototype methods |
Supported |
Not Supported |
string-keyed methods |
Supported |
Not Supported |
computed prototype methods |
Supported |
Not Supported |
optional semicolons |
Supported |
Not Supported |
static methods |
Supported |
Not Supported |
computed static methods |
Supported |
Not Supported |
accessor properties |
Supported |
Not Supported |
computed accessor properties |
Supported |
Not Supported |
static accessor properties |
Supported |
Not Supported |
computed static accessor properties |
Supported |
Not Supported |
class name is lexically scoped |
Supported |
Not Supported |
computed names, temporal dead zone |
Supported |
Not Supported |
methods aren't enumerable |
Supported |
Not Supported |
constructor requires new |
Supported |
Not Supported |
extends |
Supported |
Not Supported |
extends expressions |
Supported |
Not Supported |
extends null |
Supported |
Not Supported |
new.target |
Supported |
Not Supported |
Super
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
statement in constructors |
Supported |
Not Supported |
expression in constructors |
Supported |
Not Supported |
in methods, property access |
Supported |
Not Supported |
in methods, method calls |
Supported |
Not Supported |
method calls use correct "this" binding |
Supported |
Not Supported |
constructor calls use correct "new.target" binding |
Supported |
Not Supported |
is statically bound |
Supported |
Not Supported |
super() invokes the correct constructor |
Supported |
Not Supported |
Map
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic functionality |
Supported |
Not Supported |
constructor arguments |
Supported |
Not Supported |
constructor requires new |
Supported |
Not Supported |
constructor accepts null |
Supported |
Not Supported |
constructor invokes set |
Supported |
Not Supported |
iterator closing |
Supported |
Not Supported |
Map.prototype.set returns this |
Supported |
Not Supported |
-0 key converts to +0 |
Supported |
Not Supported |
Map.prototype.size |
Supported |
Not Supported |
Map.prototype.delete |
Supported |
Not Supported |
Map.prototype.clear |
Supported |
Not Supported |
Map.prototype.forEach |
Supported |
Not Supported |
Map.prototype.keys |
Supported |
Not Supported |
Map.prototype.values |
Supported |
Not Supported |
Map.prototype.entries |
Supported |
Not Supported |
Map.prototype[Symbol.iterator] |
Supported |
Not Supported |
Map.prototype isn't an instance |
Supported |
Not Supported |
Map iterator prototype chain |
Supported |
Not Supported |
Map[Symbol.species] |
Supported |
Not Supported |
"The Map object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and primitive values) may be used as either a key or a value.
Object is similar to Mapbboth let you set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. For this reason (and because there were no built-in alternatives), Object has been used as Map historically.
However, there are important differences that make Map preferable in some cases:
- Accidental Keys (objects initialize with prototype)
- Key types (previously just strings or symbols, now can be functions, objects, any primitive)
- Key Order (simplified to order of entry insertion)
- Size (inherent size property)
- Iteration (objects aren’t inherently iterable)
- Performance (additions and removals are more performative)
- Serialization and parsing (object wins in this case)" Reference this.
(function executeRule(current, previous /*null when async*/) {
var inc_gr = new GlideRecord('incident');
inc_gr.orderByDesc('number');
inc_gr.setLimit(3);
inc_gr.query();
const incidents = new Map();
const keyString = 'a string';
const keyObj = {};
const keyFunc = function() {};
inc_gr.next();
incidents.set(keyString, inc_gr.getValue('short_description'));
inc_gr.next();
incidents.set(keyObj, inc_gr.getValue('short_description'));
inc_gr.next();
incidents.set(keyFunc, inc_gr.getValue('short_description'));
let work_notes = [];
work_notes.push('map size: ' + incidents.size);
work_notes.push(incidents.get(keyString));
work_notes.push(incidents.get(keyObj));
work_notes.push(incidents.get(keyFunc)); //Finding an a value by providing a function!
work_notes.push(incidents.get('a string'));
current.work_notes = work_notes.join('\n');
})(current, previous);
Set
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic functionality |
Supported |
Not Supported |
constructor arguments |
Supported |
Not Supported |
constructor requires new |
Supported |
Not Supported |
constructor accepts null |
Supported |
Not Supported |
constructor invokes add |
Supported |
Not Supported |
iterator closing |
Supported |
Not Supported |
Set.prototype.add returns this |
Supported |
Not Supported |
-0 key converts to +0 |
Supported |
Not Supported |
Set.prototype.size |
Supported |
Not Supported |
Set.prototype.delete |
Supported |
Not Supported |
Set.prototype.clear |
Supported |
Not Supported |
Set.prototype.forEach |
Supported |
Not Supported |
Set.prototype.keys |
Supported |
Not Supported |
Set.prototype.values |
Supported |
Not Supported |
Set.prototype.entries |
Supported |
Not Supported |
Set.prototype[Symbol.iterator] |
Supported |
Not Supported |
Set.prototype isn't an instance |
Supported |
Not Supported |
Set iterator prototype chain |
Supported |
Not Supported |
Set[Symbol.species] |
Supported |
Not Supported |
Symbol
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
basic functionality |
Supported |
Not Supported |
typeof support |
Supported |
Not Supported |
symbol keys are hidden to pre-ES6 code |
Supported |
Not Supported |
Object.defineProperty support |
Supported |
Not Supported |
symbols inherit from Symbol.prototype |
Supported |
Not Supported |
new Symbol() throws |
Supported |
Not Supported |
JSON.stringify ignores symbol primitives |
Supported |
Not Supported |
global symbol registry |
Supported |
Not Supported |
Object static methods
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Object.assign |
Supported |
Not Supported |
Object.is |
Supported |
Not Supported |
Object.getOwnPropertySymbols |
Supported |
Not Supported |
Function "name" property
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
variables (function) |
Supported |
Not Supported |
object methods (function) |
Supported |
Not Supported |
shorthand methods |
Supported |
Not Supported |
shorthand methods (no lexical binding) |
Supported |
Not Supported |
class statements |
Supported |
Not Supported |
class expressions |
Supported |
Not Supported |
class prototype methods |
Supported |
Not Supported |
class static methods |
Supported |
Not Supported |
String static methods
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
String.raw |
Supported |
Not Supported |
String.fromCodePoint |
Supported |
Not Supported |
String.prototype methods
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
String.prototype[Symbol.iterator] |
Supported |
Not Supported |
String iterator prototype chain |
Supported |
Not Supported |
RegExp.prototype properties
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
RegExp.prototype.flags |
Supported |
Not Supported |
RegExp.prototype[Symbol.replace] |
Supported |
Not Supported |
RegExp.prototype[Symbol.split] |
Supported |
Not Supported |
RegExp[Symbol.species] |
Supported |
Not Supported |
Array static methods
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Array.from, array-like objects |
Supported |
Not Supported |
Array.from, generic iterables |
Supported |
Not Supported |
Array.from, instances of generic iterables |
Supported |
Not Supported |
Array.from map function, array-like objects |
Supported |
Not Supported |
Array.from map function, generic iterables |
Supported |
Not Supported |
Array.from map function, instances of iterables |
Supported |
Not Supported |
Array.from, iterator closing |
Supported |
Not Supported |
Array.of |
Supported |
Not Supported |
Array[Symbol.species] |
Supported |
Not Supported |
Array.prototype methods
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Array.prototype.copyWithin |
Supported |
Not Supported |
Array.prototype.find |
Supported |
Not Supported |
Array.prototype.findIndex |
Supported |
Not Supported |
Array.prototype.fill |
Supported |
Not Supported |
Array.prototype.keys |
Supported |
Not Supported |
Array.prototype.values |
Supported |
Not Supported |
Array.prototype.entries |
Supported |
Not Supported |
Array.prototype[Symbol.iterator] |
Supported |
Not Supported |
Array iterator prototype chain |
Supported |
Not Supported |
Array.prototype[Symbol.unscopables] |
Supported |
Not Supported |
Number properties
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Number.isFinite |
Supported |
Not Supported |
Number.isInteger |
Supported |
Not Supported |
Number.isSafeInteger |
Supported |
Not Supported |
Number.isNaN |
Supported |
Not Supported |
Number.EPSILON |
Supported |
Not Supported |
Number.MIN_SAFE_INTEGER |
Supported |
Not Supported |
Number.MAX_SAFE_INTEGER |
Supported |
Not Supported |
Math methods
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Math.clz32 |
Supported |
Not Supported |
Math.imul |
Supported |
Not Supported |
Math.sign |
Supported |
Not Supported |
Math.log10 |
Supported |
Not Supported |
Math.log2 |
Supported |
Not Supported |
Math.log1p |
Supported |
Not Supported |
Math.expm1 |
Supported |
Not Supported |
Math.cosh |
Supported |
Not Supported |
Math.sinh |
Supported |
Not Supported |
Math.tanh |
Supported |
Not Supported |
Math.acosh |
Supported |
Not Supported |
Math.asinh |
Supported |
Not Supported |
Math.atanh |
Supported |
Not Supported |
Math.trunc |
Supported |
Not Supported |
Math.fround |
Supported |
Not Supported |
Math.cbrt |
Supported |
Not Supported |
Math.hypot |
Supported |
Not Supported |
Date.prototype[Symbol.toPrimitive]
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
Date.prototype[Symbol.toPrimitive] |
Supported |
Not Supported |
ECMAScript 5 features
String properties and methods
Feature |
ECMAScript 2021 (ES12) |
ES5 Standards |
String.prototype.split |
Supported |
Not Supported |
Resources
https://developer.servicenow.com/blog.do?p=/post/tokyo-ecmascript-2021/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
⚠️This is a work in progres. Feel free to add examples in the comment or if you want to be a Contributor, let me know.
- 4,124 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
That's really great...thanks a lot : )