These are some of my syntactic sugar ideas for JavaScript.
#define add(a,b) a+b
console.log(add(4,7)); //Will output 11.
#define array [2,3]
console.log(array.pop()+array[1]); //Will output 6.Useful for code golfing.
But its biggest purpose is for debugging like in this example:
#define DEBUG
for(var i=0;i<iterations;i++){
#ifdef DEBUG
debugFunction(param1,param2,param3);
#else
normalFunction(param1,param2,param3);
#endif
}Instead of:
const DEBUG=true;
for(var i=0;i<iterations;i++){
if(DEBUG){
debugFunction(param1,param2,param3);
}else{
normalFunction(param1,param2,param3);
}
}So you could keep parts of your code without ruining your performance with if-statements, comments do exist of course but I get tired of uncommenting and commenting especially if they're spread separately in different areas.
Looping without using any variables.
loop{ //You could do `for(;;){`.
//Infinite loop.
}
loop(7){
//Loop 7 times.
}Instead of:
var object={
a:"Hello",
get b(){return this.a;},
set b(value){this.a=value;}
};Do this:
var object={
["a","b"]:"Hello"
};
object.a="Test";
console.log(object.a); //Will output "Test".
console.log(object.b); //Will output "Test".This can sometimes be useful for dictionaries (e.g. the array can consist of synonyms and the value can be a definition).
This can also be useful for GLSL-like vectors (e.g. ({[..."xrs0"]:0,[..."ygt1"]:0,[..."zbp2"]:0,[..."waq3"]:0})).
Instead of:
var array=[0,1];
console.log(array.reduce((t,e)=>t[e],[[6,3],6])); //Will output 3.Do this:
var array=[0,1];
console.log([[6,3],6]array); //Same as `[[6,3],6][0][1]` and will output 3.Where self's value is the variable itself:
var incrediblyLongVariableName="llo";
incrediblyLongVariableName="He"+self+", world!";
console.log(incrediblyLongVariableName); //Will output "Hello, world!".
var object={a:3,b:7,c:self.a+self.b};
//`object.c=object.a+object.b;` would've been here without `self`.
console.log(object.c); //Will output 10.Can be used for negating booleans (e.g. boolean=!self;) and recursive anonymous functions such as:
console.log((x=>x>1?Math.log(x)**self(x-1):x)(6));It can also be used for polyfills:
globalObject.prototype.method=self|function method(...arguments){
//...
};Afterthought: What about this? itself which is the value of the current local object (scope) it's being inside of?
From this:
var temp0={
y:5,
get x(){return this.y;},
set x(v){this.y=v;}
};
temp0.z=[0,undefined];
temp0.z[1]=temp0.z;
var temp1=n=>n<2?n:temp1(n-1)+temp1(n-2);
var result=(o=>temp1(o.x))(temp0);To this:
var result=(o=>(n=>n<2?n:itself(n-1)+itself(n-2))(o.x))({x:itself.y,y:5,z:[0,itself]});Another afterthought: Why can't we use temporary "variables", like this:
x:longVariableName=(6/x)+x;Which becomes:
longVariableName=(6/longVariableName)+longVariableName;Similar to this feature:
#define x longVariableName
x=(6/x)+x;Instead of:
(
var x=longVariableName;
longVariableName=(6/x)+x;
)(); //Wrapped in an anonymous function so that `x` isn't defined.Instead of:
var a="foo";
if(a=="foo"){
console.log('Got "foo".');
}else if((()=>{a+="bar";return a=="bazbar";})()){
console.log('Got "baz".');
}
while((()=>{a+="bar";return a.length<20;})()){
console.log(a);
}Do this:
var a="foo";
if(a=="foo"){
console.log('Got "foo".');
}else if(a+="bar";a=="bazbar"){
console.log('Got "baz".');
}
while(a+="bar";a.length<20){
console.log(a);
}Actually, with commas you can achieve the same effect:
var a="foo";
if(a=="foo"){
console.log('Got "foo".');
}else if(a+="bar",a=="bazbar"){
console.log('Got "baz".');
}
while(a+="bar",a.length<20){
console.log(a);
}Instead of:
(async()=>{
console.log("Sleeping for two seconds.");
await new Promise(resolve=>setTimeout(resolve,2000));
console.log("Done.");
})();Do this:
console.log("Sleeping for two seconds.");
sleep(2000);
console.log("Done.");Instead of:
var string="";
function A(){string+="Hello ";B();};
function B(){string+="there! ";C();};
function C(){string+="How are you?";};
A();
console.log(string); //Will output "Hello there! How are you?".Do this:
var string="";
goto A;
B:string+="there! ";goto C;
A:string+="Hello ";goto B;
C:string+="How are you?";
console.log(string); //Will output "Hello there! How are you?".var x=4;
link y,x;
y++;
console.log(x); //Will output 5.Which in C would be like:
int x=4;
int*y=&x;
(*y)++;
printf("%d",x);Can be used for variables with long names but I'd recommend this instead in some cases.
class vec2{
constructor(x,y){
this.x=x;
this.y=y;
}
__plus(left){
return{x:left.x+this.x,y:left.y+this.y};
}
__minus(left){
return{x:left.x-this.x,y:left.y-this.y};
}
}
console.log(new vec2(6,4)+new vec2(3,9)); //Will output {x:9,y:13}.or
overload # (left:Number,right:Number){
return left+right;
}
console.log(5#8); //Will output 13.Instead of:
console.log("foo bar baz".replace(/a/g,"e").replace(/o/g,"u")); //Output will be "fuu ber bez".Do this:
console.log("foo bar baz".replace([/a/g,/o/g],["e","u"])); //Output will be "fuu ber bez".Or even this, so you can easily comprehend the correlations:
console.log("foo bar baz".replace([[/a/g,"e"],[/o/g,"u"]])); //Output will be "fuu ber bez".Such as named capturing groups, if-then-else conditionals (e.g. (?(?=condition)then|else)), lookbehinds (e.g. (?=condition)match) and etc..
I've seen Wren doing this, useful for debugging or describing a metalanguage. Example:
/*
breaksStuff(x);
/*
Some text here.
Another line.
*/
ignored();
*/
doThis();A getTimeouts() function to return all timeoutIDs and more information about their elapsed time, functions and additional parameters, don't forget about getIntervals() for intervalIDs. Also allow the delay to be greater than 2147483647 milliseconds.
Where this:
var x=2;
switch(x){
case 2:
case 5:
console.log("First.");
break 5;
console.log("Second.");
}Becomes this:
var x=2;
switch(x){
case 2:
case 5:
console.log("First.");
if(x===5){break;}
console.log("Second.");
}And this:
var x=0;
switch(x){
case 6:
console.log("Done!");
break;
default:
console.log(x);
x++;
continue;
}Becomes this:
var x=0;
while(true){
if(x===6){
console.log("Done!");
break;
}else{
console.log(x);
x++;
}
}