In my research, I've undertaken an evaluation to estimate the potential benefits of introducing new syntax improvements in JavaScript. On one side, I've analyzed the number of cases where the proposed syntax enhancements could be utilized. On the other side, I've examined the prevalence of Nullish coalescing assignment, logical OR assignment, and
logical AND assignments and identified scenarios where it is currently used or could be employed.
PART I
I've crafted a set of regular expressions with the aim of quantifying the instances where implementing the proposed new syntax is feasible. These expressions are designed to accommodate various coding styles, accounting for differences such as spacing variations and line breaks.
- Identifies instances where a variable is assigned a value based on a truthy condition within an
if
statement block.
if\s*\(\s*((\w+\.)*\w+)\s*\)\s*\{\s*\n*\s*(\w+\.)*\w+\s*=\s*\1;\s*\n*\s*\}(?!\s*else)
Example cases:
if (b) {
a = b;
}
if (objB.prop2) {
objA.prop1 = objB.prop2;
}
if (b) { a = b; }
if (objB.prop2) { objA.prop1 = objB.prop2; }
1a) Extends Regex 1 to specifically target cases where the condition involves checking inequality with null
or undefined
.
if\s*\(\s*((\w+\.)*\w+)\s*!=+\s*(null|undefined)\s*\)\s*\{\s*\n*\s*(\w+\.)*\w+\s*=\s*\1;\s*\n*\s*\}(?!\s*else)
Example cases:
if (b !== null) { // !== or !=, null or undefined
a = b;
}
if (objB.prop2 !== null) {
objA.prop1 = objB.prop2;
}
if (b !== null) { a = b; }
if (objB.prop2 !== null) { objA.prop1 = objB.prop2; }
- Identifies cases of single-line variable assignments within an
if
statement block.
if\s*\(\s*((\w+\.)*\w+)\s*\)\s*\n*\s*(\w+\.)*\w+\s*=\s*\1;\s*\n*(?!\s*else)
Example cases:
if (b) a = b;
if (b)
a = b;
if (objB.prop2) objA.prop1 = objB.prop2; // any level of nesting
if (objB.prop2)
objA.prop1 = objB.prop2;
2a) Extends Regex 2 to specifically target cases involving inequality checks with null
or undefined
.
if\s*\(\s*((\w+\.)*\w+)\s*!=+\s*(null|undefined)\s*\)\s*\n*\s*(\w+\.)*\w+\s*=\s*\1;\s*\n*(?!\s*else)
Example cases:
if (b !== null) a = b; // !== or !=, null or undefined
if (b !== null)
a = b;
if (objB.prop2 !== null) objA.prop1 = objB.prop2; // any level of nesting
if (objB.prop2 !== null)
objA.prop1 = objB.prop2;
Please note that I deliberately exclude the following two cases:
if (b) {
a = b;
} else ... // some alternative logic
if (b) {
... // some other logic
a = b;
... // some other logic
}
These exclusions are made because such cases typically do not present opportunities for benefiting from the proposed syntax.
- Matches instances where a variable is assigned the result of a nullish coalescing operation (
??
).
[\s\n](\w+\.\w+)\s*=(\s*((\w+\.)*\w+)\s*\?\?\s*)\1;
Example cases:
a = b ?? ... ?? a;
objA.prop1 = objB.prop2 ?? ... ?? objA.prop1;
- Identifies cases where a variable is assigned the result of a logical OR operation (
||
).
[\s\n](\w+\.\w+)\s*=(\s*((\w+\.)*\w+)\s*\|\|\s*)\1;
Example cases:
a = b || ... || a;
objA.prop1 = objB.prop2 || ... || objA.prop1;
- Matches instances where a variable is assigned the result of a logical AND operation (
&&
).
[\s\n](\w+\.\w+)\s*=(\s*((\w+\.)*\w+)\s*&&\s*)\1;
Example cases:
a = b && ... && a;
objA.prop1 = objB.prop2 && ... && objA.prop1;
After conducting a search using these regular expressions in VSCode across several locally accessible projects, here are the results:
| Project | regex 1 | regex 1a | regex 2 | regex 2a | regex 3 | regex 4 | regex 5 | Total |
|-----------|---------|----------|---------|----------|---------|---------|---------|-------|
| Project 1 | 61 | 1 | 19 | 0 | 4 | 7 | 0 | 92 |
| Project 2 | 59 | 2 | 14 | 0 | 0 | 3 | 0 | 78 |
| Project 3 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 2 |
| Total | 122 | 3 | 33 | 0 | 4 | 10 | 0 | 172 |
PART II
In this section, I focus on exploring how often Nullish coalescing assignment and logical assignments are used or could be useful. Using the following search patterns, I will look through code to find examples of these features being used.
- Identifies cases where a variable is assigned a value when it is falsy within an
if
statement block.
if\s*\(\s*!((\w+\.)*\w+)\s*\)\s*\{\s*\n*\s*\1\s*=\s*(\w+\.)*\w+;\s*\n*\s*\}(?!\s*else)
Example cases:
if (!a) {
a = b;
}
if (!objA.prop1) {
objA.prop1 = objB.prop2;
}
if (!a) { a = b; }
if (!objA.prop1) { objA.prop1 = objB.prop2; }
1a) Targets cases where a variable is assigned a value when it is explicitly equal to null
or undefined
within an if
statement block.
if\s*\(\s*((\w+\.)*\w+)\s*=+\s*(null|undefined)\s*\)\s*\{\s*\n*\s*\1\s*=\s*(\w+\.)*\w+;\s*\n*\s*\}(?!\s*else)
Example cases:
if (a === null) { // === or ==, null or undefined
a = b;
}
if (objA.prop1 === null) {
objA.prop1 = objB.prop2;
}
if (a === null) { a = b; }
if (objA.prop1 === null) { objA.prop1 = objB.prop2; }
- Matches instances of single-line variable assignments within an
if
statement block.
if\s*\(!\s*((\w+\.)*\w+)\s*\)\s*\n*\s*\1\s*=\s*(\w+\.)*\w+;\s*\n*(?!\s*else)
Example cases:
if (!a) a = b;
if (!a)
a = b;
if (!objA.prop1) objA.prop1 = objB.prop2; // any level of nesting
if (!objA.prop1)
objA.prop1 = objB.prop2;
2a) Targets single-line variable assignments within an if
statement block when the condition checks for equality with null
or undefined
.
if\s*\(\s*((\w+\.)*\w+)\s*=+\s*(null|undefined)\s*\)\s*\n*\s*\1\s*=\s*(\w+\.)*\w+;\s*\n*(?!\s*else)
Example cases:
if (a === null) a = b; // === or ==, null or undefined
if (a === null)
a = b;
if (objA.prop1 === null) objA.prop1 = objB.prop2; // any level of nesting
if (objA.prop1 === null)
objA.prop1 = objB.prop2;
- Matches nullish coalescing assignments.
[\s\n](\w+\.\w+)\s*=\s*\1(\s*\?\?\s*(\w+\.)*\w+)+;
Example cases:
a = a ?? b ?? ...;
objA.prop1 = objA.prop1 ?? objB.prop2 ?? ...;
- Identifies cases of logical OR assignments.
[\s\n](\w+\.\w+)\s*=\s*\1(\s*\|\|\s*(\w+\.)*\w+)+;
Example cases:
a = a || b || ...;
objA.prop1 = objA.prop1 || objB.prop2 || ...;
- Matches cases of logical AND assignments.
[\s\n](\w+\.\w+)\s*=\s*\1(\s*&&\s*(\w+\.)*\w+)+;
Example cases:
a = a && b && ...;
objA.prop1 = objA.prop1 && objB.prop2 && ...;
- Identifies nullish coalescing assignments with the
??=
operator.
[\s\n](\w+\.\w+)*\s*\?\?=
Example cases:
a ??= ...;
objA.prop1 ??= ...;
- Matches logical OR assignments with the
||=
operator.
[\s\n](\w+\.\w+)*\s*\|\|=
Example cases:
a ||= ...;
objA.prop1 ||= ...;
- Identifies logical AND assignments with the
&&=
operator.
[\s\n](\w+\.\w+)*\s*&&=
Example cases:
a &&= ...;
objA.prop1 &&= ...;
After conducting a search using these regular expressions in VSCode across same locally accessible projects, here are the results:
| Project | regex 1 | regex 1a | regex 2 | regex 2a | regex 3 | regex 4 | regex 5 | regex 6 | regex 7 | regex 8 | Total |
|-----------|---------|----------|---------|----------|---------|---------|---------|---------|---------|---------|-------|
| Project 1 | 17 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 19 |
| Project 2 | 8 | 1 | 6 | 0 | 0 | 2 | 0 | 0 | 1 | 0 | 18 |
| Project 3 | 1 | 2 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 6 |
| Total | 26 | 3 | 7 | 0 | 0 | 5 | 0 | 0 | 2 | 0 | 43 |
In conclusion, the results of my preliminary local research suggest that the newly proposed syntax enhancements have even greater potential for adoption compared to the existing syntax of Nullish coalescing assignment and logical assignments. However, to further validate these findings and ensure objectivity, I encourage others to conduct similar analyses in their own projects. Additionally, exploring open-source projects could provide valuable insights into the broader adoption of these syntax enhancements in the JavaScript community.