81

Here are some gems:

Literals:

var obj = {}; // Object literal, equivalent to var obj = new Object();
var arr = []; // Array literal, equivalent to var arr = new Array();
var regex = /something/; // Regular expression literal, equivalent to var regex = new RegExp('something');

Defaults:

arg = arg || 'default'; // if arg evaluates to false, use 'default', which is the same as:
arg = !!arg ? arg : 'default';

Of course we know anonymous functions, but being able to treat them as literals and execute them on the spot (as a closure) is great:

(function() { ... })(); // Creates an anonymous function and executes it

Question: What other great syntactic sugar is available in javascript?

eyelidlessness
  • 60,651
  • 11
  • 88
  • 93
  • 2
    I wasn't aware of that || default value syntax. Nice and compact, though not so intuitive. (Maybe I *have* seen it, but never understood it.) – Chris Noe Oct 08 '08 at 00:37
  • 1
    I had a much harder time grasping ternary syntax. It'll seem like second nature after you write it a few times. As far as places you may have seen it, I think both jquery.js and prototype.js use it. – eyelidlessness Oct 08 '08 at 02:06
  • 1
    How about explaining each of the examples? – pc1oad1etter Oct 22 '08 at 01:35
  • 2
    I didn't know about "arg || 'default'". I would expect it to return a boolean value, but it returns the first value (from the left) that evaluates to true (similar to python)! It's much better than "arg = arg ? arg : 'default'"! – Jamol Dec 28 '09 at 06:59
  • Chris Noe pawned this thread! – Mahesh Velaga Apr 18 '10 at 01:52
  • You should add to the (function(){})(); that it's mainly used for bookmarklets, so the browser won't redirect to the result of the lsat expression. – tstenner Aug 19 '10 at 18:37
  • The `arg || 'default'` syntax is also a bit (15%) faster, I added a quick benchmark here: http://jsperf.com/boolean-conditionals-vs-ternary – adamJLev Aug 20 '10 at 15:35
  • arg || 'default' doesn't work if you want a 'falsy' arg of a particular type. arg === undefined ? default : arg is much safer. – Gregg Lind Nov 22 '10 at 22:55
  • @Gregg, I suppose it depends on expected input. Typically, if I'm writing a function where an argument might be more than one of the possible "falsy" values, I consider this a problem with the design and I'll try to refactor. That said, I'll clarify the sugar so it's clear what it means. – eyelidlessness Nov 23 '10 at 00:18

31 Answers31

58

Getting the current datetime as milliseconds:

Date.now()

For example, to time the execution of a section of code:

var start = Date.now();
// some code
alert((Date.now() - start) + " ms elapsed");
Kulvar
  • 1,079
  • 8
  • 22
Chris Noe
  • 35,223
  • 22
  • 68
  • 90
  • This is, in fact, the best javascript syntactic sugar. A winnar si yuo. – eyelidlessness Oct 22 '08 at 08:52
  • 3
    OrbMan, that probably depends on the context; if passing it as an argument, it may be coerced to an Object rather than to a Number or a String, in which case the + would have already coerced it to a Number. In fact, + appears to function as a shorthand for parseInt(value, 10). – eyelidlessness Aug 11 '09 at 00:33
  • Correction: it does have some difference from parseInt(value, 10). For instance, +[3] and parseInt([3], 10) are both equal to the number 3, but +[3, 4] == NaN and parseInt([3, 4], 10) == 3. – eyelidlessness Aug 11 '09 at 00:37
  • Er... all of those instances of parseInt(value, 10) ought to be parseFloat(value). And Chris Noe, sorry for the comment spam ;) – eyelidlessness Aug 11 '09 at 00:40
  • alert(new Date() + new Date()); // double the years from year 0 to now. – Omar Al-Ithawi Nov 16 '11 at 18:51
  • 1
    My curiosity pushed my to try it in jsperf and it seems that the most performant is the canonical getTime() :) (ref. http://jsperf.com/millisecondsdate) – sirLisko May 12 '12 at 10:16
  • Isn't it nicer (or 'more sugary') to just define a function so you can write `now()`? – mhelvens Dec 28 '13 at 13:13
  • Virtually none of the answers or comments to this question are actually syntax sugar (I count 2 that would actually qualify) and most of the rest of them are just misidentifying/misusing the boolean operators or are things that exist in every language ever, or both. – Ehren Murdick Aug 23 '21 at 19:54
33

Object membership test:

var props = { a: 1, b: 2 };

("a" in props) // true
("b" in props) // true
("c" in props) // false
Chris Noe
  • 35,223
  • 22
  • 68
  • 90
26

In Mozilla (and reportedly IE7) you can create an XML constant using:

var xml = <elem></elem>;

You can substitute variables as well:

var elem = "html";
var text = "Some text";
var xml = <{elem}>{text}</{elem}>;
Chris Noe
  • 35,223
  • 22
  • 68
  • 90
  • Really? Are there other engines which support that? – eyelidlessness Oct 07 '08 at 23:42
  • 1
    Just wondering: what can you do with that "xml" variable once you've created it? Just playing with it now in firebug, it looks as though it doesn't have any methods or properties and you can't add it to the DOM. – nickf Oct 08 '08 at 00:14
  • Helpful link: http://developer.mozilla.org/index.php?title=En/Core_JavaScript_1.5_Guide/Processing_XML_with_E4X – Chris Noe Oct 08 '08 at 00:23
  • You can do this in scala too! – Steve g Oct 09 '08 at 21:05
  • Rhino supports this as well (open source Javascript engine for Java): http://www.mozilla.org/rhino/ – J c Nov 21 '08 at 13:25
  • @nickf: e4x is great!!! I've been using it for a while with JSDB to output HTML pages and do processing on XML. var x=b; x.a += cc; x.a[0].@n = 3; for each (var c in x.children()) print("wow:"+c.toXMLString()); (prints this: wow:b wow:cc ) – Jason S Dec 09 '08 at 14:15
  • 8
    E4X literals are a security disaster due to cross-site-script-inclusion attacks, and really not noticeably better than just being able to say “var xml= new XML('')” IMO. – bobince Mar 06 '09 at 23:18
  • @bobince If the attacker can inject Javascript, you're gone regardless of whether E4X is on or not –  Feb 08 '10 at 11:15
  • 2
    @CharlieSomerville That's not the risk. E4X potentially turns ‘safe’ [X][HT]ML files into active JS. Please read http://code.google.com/p/doctype/wiki/ArticleE4XSecurity for background on this issue. – bobince Feb 08 '10 at 13:07
26

Using anonymous functions and a closure to create a private variable (information hiding) and the associated get/set methods:

var getter, setter;

(function()
{
   var _privateVar=123;
   getter = function() { return _privateVar; };
   setter = function(v) { _privateVar = v; };
})()
Ash
  • 59,110
  • 31
  • 149
  • 168
  • took me a moment, but i got it. this IS neat. – matt lohkamp Oct 09 '08 at 09:48
  • I discovered a similar technique a while ago while looking through the swfobject source. Using closures to create private variables/methods is something I probably never would have thought of. It's kind of cool. – Herms Mar 31 '09 at 13:42
  • With the new JS version, we can use the simpler `if(true) { let _privateVar=123; }` – Kulvar Nov 16 '16 at 09:37
  • Be aware of the "dog balls" stylistic potential issue here. See: https://twitter.com/paul_irish/status/176187448420864000?lang=en – Jonathan.Brink Jun 01 '17 at 16:55
22

Being able to extend native JavaScript types via prototypal inheritance.

String.prototype.isNullOrEmpty = function(input) {
    return input === null || input.length === 0;
}
steve_c
  • 6,061
  • 4
  • 29
  • 41
  • 6
    Just avoid doing this to Array: http://stackoverflow.com/questions/61088/hidden-features-of-javascript#118556 – Chris Noe Oct 08 '08 at 00:17
  • This is true, but only if you use the for(a in b) loop. Typically I use frameworks, as I'm sure everyone else does. As a consequence I'm typically using .each() – steve_c Oct 08 '08 at 00:35
  • It's a potential problem if *any* code in your container uses for(a in b). And when that container is a browser, you could be breaking other code in your browser, (eg, that framework). I have been dinged by the one. – Chris Noe Oct 08 '08 at 00:42
  • Yep. Good points, Chris. I still count prototypal inheritance as one of the best features of JavaScript :) – steve_c Oct 08 '08 at 00:52
  • for(var i in obj) { if(!obj.hasOwnProperty(i)) { continue; } ... } – eyelidlessness Oct 08 '08 at 02:12
  • Yep, You should always use hasOwnProperty otherwise the loop will iterate over all properties up the prototype chain. – steve_c Oct 13 '08 at 19:42
  • This is more than extension method in .NET – linquize May 21 '12 at 06:15
21

Resize the Length of an Array

length property is a not read only. You can use it to increase or decrease the size of an array.

var myArray = [1,2,3];
myArray.length // 3 elements.
myArray.length = 2; //Deletes the last element.
myArray.length = 20 // Adds 18 elements to the array; the elements have the empty value. A sparse array.
user7393973
  • 2,118
  • 1
  • 15
  • 51
pramodc84
  • 1,550
  • 2
  • 26
  • 32
  • 1
    Sir, this must be the single most important answer on SO, I believe. No more `push`ing for me, hehe. Thanks a bunch. – aefxx Nov 23 '10 at 00:29
  • 4
    actually, the created elements using this way don't actually exist (they don't have the undefined value either, but accessing them will get you undefined). You also can't iterate over them with for..in. – yorick Jan 19 '11 at 17:55
21

Use === to compare value and type:

var i = 0;
var s = "0";

if (i == s)  // true

if (i === s) // false
Chris Noe
  • 35,223
  • 22
  • 68
  • 90
  • It's actually referred to as strict equal -- basically it avoids all the type conversions that otherwise have to happen when doing == – olliej Oct 07 '08 at 23:54
  • other languages (PHP) also call it "identity" checking, ie: are these two values *identical*? – nickf Oct 08 '08 at 00:15
  • @nickf, it's a bit of a misnomer. `$var1 = 'string'; $var2 = 'string'; $var1 === $var2; // true`, even though `$var1` and `$var2` are not identical (references to same stored value in memory), just the same type and same value. – eyelidlessness Dec 18 '10 at 18:17
  • @eyelidlessness, I'm not sure that javascript works that way... strings are *(usually)* stored and passed by value. Objects however are stored as a reference: `var1 = {a : 'b'}; var2 = {a : 'b'}; var1 === var2 // false`. – nickf Dec 19 '10 at 16:57
  • @nickf, I understand that. But you can remove the sigil in the PHP code and get the same result in JavaScript. Those strings are not *identical*, but their values are. – eyelidlessness Dec 19 '10 at 20:40
21

Multi-line strings:

var str = "This is \
all one \
string.";

Since you cannot indent the subsequent lines without also adding the whitespace into the string, people generally prefer to concatenate with the plus operator. But this does provide a nice here document capability.

Chris Noe
  • 35,223
  • 22
  • 68
  • 90
16

Repeating a string such as "-" a specific number of times by leveraging the join method on an empty array:

var s = new Array(repeat+1).join("-");

Results in "---" when repeat == 3.

J c
  • 6,297
  • 3
  • 28
  • 29
15

Like the default operator, || is the guard operator, &&.

answer = obj && obj.property

as opposed to

if (obj) {
    answer = obj.property;
}
else {
    answer = null;
}
Skilldrick
  • 67,147
  • 33
  • 171
  • 227
  • 1
    It doesn't necessarily have to be `null`. This is only the case when `obj === null`. – pimvdb Aug 31 '11 at 10:59
  • 1
    Can also be used in conjunction with || to ensure a backup in the case that either obj doesn't exist at all OR the object exists but the key property doesn't. This way answer is always defined: answer = (obj && obj.property) || 'backupprop'; – Dtipson Jun 30 '15 at 14:58
13
var tags = {
    name: "Jack",
    location: "USA"
};

"Name: {name}<br>From {location}".replace(/\{(.*?)\}/gim, function(all, match){
    return tags[match];
});

callback for string replace is just useful.

Serkan Yersen
  • 1,103
  • 1
  • 9
  • 19
12

Getters and setters:

function Foo(bar)
{
    this._bar = bar;
}

Foo.prototype =
{
    get bar()
    {
        return this._bar;
    },

    set bar(bar)
    {
        this._bar = bar.toUpperCase();
    }
};

Gives us:

>>> var myFoo = new Foo("bar");
>>> myFoo.bar
"BAR"
>>> myFoo.bar = "Baz";
>>> myFoo.bar
"BAZ"
Jonny Buchanan
  • 60,358
  • 16
  • 139
  • 149
  • Yes, it will be a bit nicer then the current approach I used. – Ash Oct 11 '08 at 06:18
  • @eyelidlessness it is in ECMAScript 5's Object.defineProperty which IE implements and other browsers can use __defineGetter__. – Eli Grey Aug 15 '09 at 15:46
  • IE8 only implements getters/setters for DOM objects, so it's useless when it comes to making your own object APIs neater :-/ – Jonny Buchanan Aug 15 '09 at 20:57
5

This isn't a javascript exclusive, but saves like three lines of code:

check ? value1 : value2
levik
  • 109,165
  • 26
  • 72
  • 89
  • Is there an equivalent to this when not assigning a value (eg. fnName ? fnName : defaultFn;)? – eyelidlessness Oct 07 '08 at 23:54
  • 1
    No, the ternary operator is strictly for expressions; no statements – Josh Hinman Oct 08 '08 at 00:11
  • 1
    you can use it to evaluate anonymous functions, like this: "var myFunc = (browserIsIE ? function() { ... } : function() { ... })" . personally, I wouldn't recommend it since it's pretty confusing, but at least it's possible. – nickf Oct 08 '08 at 00:17
  • "evaluate" probably isn't the best word in that previous comment. Umm.. assign? – nickf Oct 08 '08 at 00:23
  • @eyelidlessness: Yes: fnName ? fnName() : defaultFn(); // on a line on its own, works – Ates Goral Oct 08 '08 at 01:11
  • Adding to my comment above, you could even do: (fnName ? fnName : defaultFn)(); – Ates Goral Oct 08 '08 at 01:12
  • @Ates Goral: It "works" but throws a ReferenceError if fnName is undefined. That's hardly syntactic sugar. – eyelidlessness Oct 08 '08 at 02:16
  • Of course, you would only do this when you know the variables to be declared. You could even go: `(fnName || defaultFn)()` – Ates Goral Aug 20 '10 at 15:17
4

Following obj || {default:true} syntax :

calling your function with this : hello(neededOne && neededTwo && needThree) if one parameter is undefined or false then it will call hello(false), sometimes usefull

vvo
  • 2,671
  • 21
  • 28
4

A little bit more on levik's example:

var foo = (condition) ? value1 : value2;
VirtuosiMedia
  • 49,626
  • 21
  • 91
  • 139
  • 4
    You don't need the parenthesis. Ternary operators are also common to many other languages. – Ates Goral Oct 08 '08 at 01:08
  • 1
    The parentheses help when there is syntactical ambiguity in the conditional statement (eg determining which component of the conditional statement the ? applies to). – eyelidlessness Sep 27 '09 at 06:45
4

The Array#forEach on Javascript 1.6

myArray.forEach(function(element) { alert(element); });
Pablo Cabrera
  • 5,654
  • 4
  • 22
  • 28
4

In parsing situations with a fixed set of component parts:

var str = "John Doe";

You can assign the results directly into variables, using the "destructuring assignment" synatx:

var [fname, lname] = str.split(" ");
alert(lname + ", " + fname);

Which is a bit more readable than:

var a = str.split(" ");
alert(a[1] + ", " + a[0]);

Alternately:

var [str, fname, lname] = str.match(/(.*) (.*)/);

Note that this is a Javascript 1.7 feature. So that's Mozilla 2.0+ and Chrome 6+ browsers, at this time.

Chris Noe
  • 35,223
  • 22
  • 68
  • 90
  • I tried this in the Safari Javascript console and it results in a parse error. – eyelidlessness Oct 12 '10 at 21:18
  • Snap, I guess I've only used this in Firefox. I have add a browser compatibility note. – Chris Noe Oct 13 '10 at 00:43
  • It doesn't work on Chrome 6. It gives `SyntaxError: Unexpected token [`. – RaYell Oct 13 '10 at 12:19
  • A little research starts to reveal that chrome's 1.7 is not entirely standard. There is reportedly a problem with let as well: http://stackoverflow.com/questions/300185/google-chrome-javascript-version#1125353 – Chris Noe Oct 14 '10 at 22:00
  • It still does not work on Chrome 13. Any clue as to when this will be implemented? – pimvdb Aug 31 '11 at 11:01
3

Immediately Invoked Arrow function:

var test = "hello, world!";
(() => test)(); //returns "hello, world!";
Gerard Simpson
  • 1,907
  • 2
  • 27
  • 42
2

I forgot:

(function() { ... }).someMethod(); // Functions as objects
eyelidlessness
  • 60,651
  • 11
  • 88
  • 93
2

Create an anonymous object literal with simply: ({})

Example: need to know if objects have the valueOf method:

var hasValueOf = !!({}).valueOf

Bonus syntactic sugar: the double-not '!!' for converting pretty much anything into a Boolean very succinctly.

mkoistinen
  • 7,566
  • 3
  • 35
  • 56
1

Assigining the frequently used keywords (or any methods) to the simple variables like ths

  var $$ = document.getElementById;

  $$('samText');
RameshVel
  • 62,788
  • 28
  • 167
  • 209
  • 3
    That won't work (in Chrome at least), because the `this` value is lost. Instead, you should use `document.getElementById.bind(document)`. Without `bind` it is merely assigning the `HTMLDocument.prototype.getElementById` function, without the information that it should be called on `document`. – pimvdb Aug 31 '11 at 11:03
1

I love being able to eval() a json string and get back a fully populated data structure. I Hate having to write everything at least twice (once for IE, again for Mozilla).

dicroce
  • 42,886
  • 27
  • 97
  • 139
1

JavaScript's Date class providing a semi-"Fluent Interface". This makes up for not being able to extract the date portion from a Date class directly:

var today = new Date((new Date()).setHours(0, 0, 0, 0));

It's not a fully Fluent Interface because the following will only give us a numerical value which is not actually a Date object:

var today = new Date().setHours(0, 0, 0, 0);
palswim
  • 11,416
  • 6
  • 50
  • 74
1

Default fallback:

var foo = {}; // empty object literal

alert(foo.bar) // will alert "undefined"

alert(foo.bar || "bar"); // will alert the fallback ("bar")

A practical example:

// will result in a type error
if (foo.bar.length === 0)

// with a default fallback you are always sure that the length
// property will be available.
if ((foo.bar || "").length === 0) 
John Carter
  • 52,342
  • 26
  • 107
  • 142
cllpse
  • 20,858
  • 36
  • 128
  • 169
1

I love how simple it is to work with lists:

var numberName = ["zero", "one", "two", "three", "four"][number];

And hashes:

var numberValue = {"zero":0, "one":1, "two":2, "three":3, "four":4}[numberName];

In most other languages this would be quite heavy code. Value defaults are also lovely. For example error code reporting:

var errorDesc = {301: "Moved Permanently",
                 404: "Resource not found",
                 503: "Server down"
                }[errorNo] || "An unknown error has occurred";
tne
  • 6,665
  • 2
  • 40
  • 65
manixrock
  • 2,493
  • 4
  • 24
  • 28
1

Here's one I just discovered: null check before calling function:

a = b && b.length;

This is a shorter equivalent to:

a = b ? b.length : null;

The best part is that you can check a property chain:

a = b && b.c && b.c.length;
pimvdb
  • 146,912
  • 75
  • 297
  • 349
ming_codes
  • 2,800
  • 21
  • 24
0
element.innerHTML = "";  // Replaces body of HTML element with an empty string.

A shortcut to delete all child nodes of element.

pramodc84
  • 1,550
  • 2
  • 26
  • 32
0

Convert string to integer defaulting to 0 if imposible,

0 | "3" //result = 3
0 | "some string" -> //result = 0
0 | "0" -> 0 //result = 0

Can be useful in some cases, mostly when 0 is considered as bad result

Raimonds
  • 526
  • 3
  • 19
0

Template literals

var a = 10;
var b = 20;
var text = `${a} + ${b} = ${a+b}`;

then the text variable will be like below!

10 + 20 = 30

Mohan Kumar
  • 611
  • 1
  • 7
  • 24
0

int to string cast

var i = 12;
var s = i+"";
Martijn Laarman
  • 13,406
  • 43
  • 63
0

optional chaining (?.) can be used so instead of:

if(error && error.response && error.response.msg){ // do something}

we can:

if(error?.response?.msg){ // do something }

more about optional chaining here

Amin Dannak
  • 145
  • 1
  • 7