CodeQL documentation

Use of platform-specific language features

ID: js/non-standard-language-feature
Kind: problem
Severity: warning
Precision: very-high
Tags:
   - portability
   - maintainability
   - language-features
   - external/cwe/cwe-758
Query suites:
   - javascript-security-and-quality.qls

Click to see the query in the CodeQL repository

Non-standard language extensions such as expression closures or let expressions should be avoided, since they make code harder to read or reuse.

Recommendation

Use standard language features instead. For instance, expression closures can be replaced by ECMAScript 2015 arrow functions, or alternatively by plain functions; let statements and expressions can be replaced by ECMAScript 2015 let declarations; and for each ... in statements can be replaced by ECMAScript 2015 for ... of statements.

Example

The following example uses an expression closure with map:

[1, 2, 3].map(function(x) x * x);

The equivalent code using an ECMAScript 2015 arrow function is as follows:

[1, 2, 3].map((x) => x * x);

On ECMAScript 2015 platforms, a plain function can be used instead:

[1, 2, 3].map(function (x) { return x * x; });

As another example, consider this use of a let statement:

function sumOfSquares(a) {
	var sum = 0;
	for (var i=0; i<a.length; ++i) {
		let (square = a[i]*a[i]) {
			sum += square;
		}
	}
	return sum;
}

It can easily be replaced by a block-scoped let declaration:

function sumOfSquares(a) {
	var sum = 0;
	for (var i=0; i<a.length; ++i) {
		let square = a[i]*a[i];
		sum += square;
	}
	return sum;
}

Older versions of Firefox support a postfix notation for array comprehensions:

var numbers = [1, 2, 3, 4, 5];
var squares = [i*i for (i of numbers)];

This notation should be converted into the semantically equivalent prefix notation supported by newer browsers:

var numbers = [1, 2, 3, 4, 5];
var squares = [for (i of numbers) i*i];

References