639

Which characters can be used for naming a JavaScript variable?

I want to create a small "extension library" for my non-JavaScript users here at work (who all seem to be squeamish when it comes to the language). I love how jQuery and Prototype have both use the $ dollar sign, and since I use jQuery, I'm looking for another nice single-character symbol to use.

I realize that I could just test out a number of characters, but I'm hoping to narrow down my list of characters to start with (in consideration of future integration with another popular library, perhaps).

Machavity
  • 30,841
  • 27
  • 92
  • 100
Richard Clayton
  • 7,452
  • 3
  • 23
  • 19
  • 16
    If you're just looking for alternative symbols, the Greek alphabet is valid (eg, `αβγδεζηθικλμνξοπρσςτυφχψω`)... or if you want to really mess up your other developers, you could go with the English alphabet, but in an alternative font (eg., `ABCDEFGHIJKLM NOPQRSTUVWXYZ abcdefghijklm nopqrstuvwxyz`) ...also valid! – ashleedawg Nov 10 '20 at 10:26

12 Answers12

1087

To quote Valid JavaScript variable names, my write-up summarizing the relevant spec sections:

An identifier must start with $, _, or any character in the Unicode categories “Uppercase letter (Lu)”, “Lowercase letter (Ll)”, “Titlecase letter (Lt)”, “Modifier letter (Lm)”, “Other letter (Lo)”, or “Letter number (Nl)”.

The rest of the string can contain the same characters, plus any U+200C zero width non-joiner characters, U+200D zero width joiner characters, and characters in the Unicode categories “Non-spacing mark (Mn)”, “Spacing combining mark (Mc)”, “Decimal digit number (Nd)”, or “Connector punctuation (Pc)”.

I’ve also created a tool that will tell you if any string that you enter is a valid JavaScript variable name according to ECMAScript 5.1 and Unicode 6.1:

JavaScript variable name validator


P.S. To give you an idea of how wrong Anthony Mills' answer is: if you were to summarize all these rules in a single ASCII-only regular expression for JavaScript, it would be 11,236 characters long. Here it is:

// ES5.1 / Unicode 6.1
/^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|undefined|NaN|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$)[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc0-9\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19d9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]*$/
Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
  • 21
    @marsbear I happen to have written an article on that as well: http://mathiasbynens.be/notes/javascript-properties And a tool, too: http://mothereff.in/js-properties#12e34 Here’s [a relevant Stack Overflow answer](http://stackoverflow.com/a/9568622/96656) of mine. – Mathias Bynens May 14 '12 at 16:24
120

From the ECMAScript specification in section 7.6 Identifier Names and Identifiers, a valid identifier is defined as:

Identifier ::
    IdentifierName but not ReservedWord

IdentifierName ::
    IdentifierStart
    IdentifierName IdentifierPart

IdentifierStart ::
    UnicodeLetter
    $
    _
    \ UnicodeEscapeSequence

IdentifierPart ::
    IdentifierStart
    UnicodeCombiningMark
    UnicodeDigit
    UnicodeConnectorPunctuation
    \ UnicodeEscapeSequence

UnicodeLetter
    any character in the Unicode categories “Uppercase letter (Lu)”, “Lowercase letter (Ll)”, “Titlecase letter (Lt)”,
    “Modifier letter (Lm)”, “Other letter (Lo)”, or “Letter number (Nl)”.

UnicodeCombiningMark
    any character in the Unicode categories “Non-spacing mark (Mn)” or “Combining spacing mark (Mc)”

UnicodeDigit
    any character in the Unicode category “Decimal number (Nd)”

UnicodeConnectorPunctuation
    any character in the Unicode category “Connector punctuation (Pc)”

UnicodeEscapeSequence
    see 7.8.4.

HexDigit :: one of
    0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

which creates a lot of opportunities for naming variables and also in golfing. Let's try some examples.

A valid identifier could start with either a UnicodeLetter, $, _, or \ UnicodeEscapeSequence. A Unicode letter is any character from these categories (see all categories):

  • Uppercase letter (Lu)
  • Lowercase letter (Ll)
  • Titlecase letter (Lt)
  • Modifier letter (Lm)
  • Other letter (Lo)
  • Letter number (Nl)

This alone accounts for some crazy possibilities - working examples. If it doesn't work in all browsers, then call it a bug, because it should.

var ᾩ = "something";
var ĦĔĽĻŎ = "hello";
var 〱〱〱〱 = "less than? wtf";
var जावास्क्रिप्ट = "javascript"; // OK, that's JavaScript in Hindi
var KingGeorgeⅦ = "Roman numerals, awesome!";
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anurag
  • 140,337
  • 36
  • 221
  • 257
  • 3
    Could you please copy your example lines to [this Rosetta Code page](http://rosettacode.org/wiki/Unicode_variable_names), which is currently lacking a JavaScript example? – Walter Tross Oct 30 '14 at 13:45
  • link in comment above should be "[this Rosetta Code page](http://rosettacode.org/wiki/Unicode_variable_names#JavaScript)". **↑** – ashleedawg Aug 06 '21 at 02:45
83

Basically, in regular expression form: [a-zA-Z_$][0-9a-zA-Z_$]*. In other words, the first character can be a letter or _ or $, and the other characters can be letters or _ or $ or numbers.

Note: While other answers have pointed out that you can use Unicode characters in JavaScript identifiers, the actual question was "What characters should I use for the name of an extension library like jQuery?" This is an answer to that question. You can use Unicode characters in identifiers, but don't do it. Encodings get screwed up all the time. Keep your public identifiers in the 32-126 ASCII range where it's safe.

Anthony Mills
  • 8,676
  • 4
  • 32
  • 51
  • 1
    I'm awarding the answer to Anthony. I looked up the ECMA standard Benj provided and found out that you can only use the _ or $. Thank you all for your help, though I'm saddened by this fact! – Richard Clayton Nov 02 '09 at 13:14
  • 3
    To further answer your question, the other character would be the underscore, as in http://documentcloud.github.com/underscore/ ... or you can always use something like `$rc` ... :) Prototype, for instance, uses `$$`, and the Microsoft Ajax Library uses $ with short words. – Anthony Mills Nov 02 '09 at 13:15
  • 9
    Don't forget π: https://twitter.com/mathias/status/71573155470245888 (yes, it works: http://jsfiddle.net/musicisair/Wqx5k/) – David Murdoch May 20 '11 at 14:04
  • 89
    I would probably plot to assassinate a co-developer who used unicode characters in his label names. /barely ironic speech – Erik Reppen Sep 16 '11 at 18:54
  • 13
    romkyns, I don't think "Unicode character identifier names" would ever be included in "JavaScript: The Good Parts", and as such, I prefer to ignore their existence. However, I have added a disclaimer to my answer for your benefit. – Anthony Mills Feb 27 '12 at 19:33
  • 14
    Regarding Encodings: please *do* use non-ASCII characters, at least in your string literals. We have to eliminate all the stupid software that gets the encodings "screwed up all the time". What a bliss to just type `Console.WriteLine("привет")` in C# and _have it actually work_! – Roman Starkov Jun 22 '12 at 19:40
  • 16
    Look, @Timwi, especially when you're writing a library (as Richard says he is), it's kind to not force your users into Alt-blah crap or copy'n'pasting. Also, for your own stuff, you might be fine with dealing with the annoyances that crop up when you run into browser or proxy server bugs or whatever, but making the users of your library deal with that stuff isn't cool. A good answer answers "what should I do" more than just dealing with the question at hand. So yes, I want to help people. I'm not going to include the useless and the dangerous information, unless I say "oh, and don't do this." – Anthony Mills Jul 08 '12 at 21:57
  • 5
    @AnthonyMills Or, you know, you might just be a person who writes in a language that isn't limited to ascii. – Kzqai Aug 09 '12 at 13:51
  • 41
    @Tchalvak For code that just you are using, that's probably fine, using Ʒ as your main library name. (Oh, you thought that was a 3? So sorry, it's actually U+01B7 Latin Capital Letter Ezh! Or was it З, Cyrillic Capital Letter Ze?) If you're going to write a library that might be used by other people, though, it's probably best to stick to ASCII. – Anthony Mills Aug 09 '12 at 14:21
  • 5
    @AnthonyMills: +1 to show the most portable (and in my eyes, Right) answer. Ie: not going beyond ASCII's [ -~] range (+ tab + newline) – Olivier Dulac Apr 25 '13 at 12:20
  • 5
    I can see it now... a competing library to jQuery called **FuzzyQuery** that does selectors by xpath with a base name of ෴ just for kicks: `෴("body/div/span#foo").huzzah(true);` ;-) – scunliffe Mar 13 '14 at 00:47
  • 2
    q̊̆̓̍u̐͂e̷̜r̤̻̫ͅy̎(".comment-body", q̊̆̓̍u̐͂e̷̜r̤̻̫ͅy̎(".comment")); Haha, I'm having fun. Sorry. I think I'll stick to simple accents that are part of extendec ascii. éàâç and the likes. – Domino Feb 12 '15 at 15:08
  • 1
    @AnthonyMills unicode simply is large enough that there are more similarly looking characters, but even ASCII having 5 (“O0” and “Il1”) of them is telling. and your answer isn’t “technically” wrong, it’s wrong. “technically” means that it’s wrong in some valid contexts. and “you not liking it” isn’t a valid context – flying sheep Mar 11 '15 at 11:57
  • 1
    @AnthonyMills I saw this mentioned somewhere a long time ago, but you can literally escape variable names and keywords with ascii-only characters. And to make things really confusing, throw in octal numbers. For instance, `\u0076a\u0072 \u0417\u0417 = 043; console.log(ЗЗ == 35) // true` – Pluto Mar 25 '15 at 20:05
  • 1
    @Pluto I didn't know that. You think you know a language... :) – Anthony Mills Apr 07 '15 at 23:36
  • 4
    @flyingsheep The question isn't "What characters are valid characters for JavaScript identifiers?" That's the title of the question, and it's part of the question, but it's not the full question. The question is: what characters are good to use in the name of a library function like jQuery's? And the answer to that is: `^[a-zA-Z_$][0-9a-zA-Z_$]*$` Not technically, literally, for the given reasons. – Anthony Mills Apr 07 '15 at 23:40
  • 3
    Note: I modified my answer to point out that I was answering the full question, not the part of the question that was "What are legal JS identifier characters". – Anthony Mills Apr 07 '15 at 23:47
  • @Anthony Mills: I think ^[a-zA-Z_$][0-9a-zA-Z_$]* is what you meant. Otherwise something like "1A" is allowed. See this JSFiddle https://jsfiddle.net/8muoc0er/1/ – Roman Dvoskin Mar 29 '16 at 20:56
  • Well, I meant it to apply to the whole thing, so yes, something like `^[a-zA-Z_$][0-9a-zA-Z_$]*$` if you're doing a verification regex (you forgot the last `$` :) ). – Anthony Mills Mar 30 '16 at 05:05
  • When you write a library, why not let the user modify the names? For example, having a set of modifying (well documented...) commands one can enter into the script url ( `...library.php?prefix=boo&suffix=hoo&function_longFunctionName=sfn ` ) and PHP script to modify the library. Staying within reason of course, option to change variable names _inside functions_ is probably not the best idea. – ElDoRado1239 Feb 07 '19 at 02:49
  • >Look, @Timwi, especially when you're writing a library (as Richard says he is), it's kind to not force your users into Alt-blah crap or copy'n'pasting. @AnthonyMills That's pretty offending statement. What about all the AltGr+space stuff I have to do just to make a backtick ` on a danish keyboard? Your statement only make sense on an english keyboard. In other countries non ASCII characters are just a single key on the keyboard. – dotnetCarpenter May 14 '19 at 10:07
  • As a speaker of a language that uses non basic ASCII characters, I wonder who on earth would really need or like to do so in identifiers. Comments are ok, though. – Petruza Apr 04 '21 at 23:46
  • that an identifier also can't be a keyword is important, your regex doesn't catch that. – Boris Verkhovskiy Apr 21 '22 at 20:27
24

Before JavaScript 1.5: ^[a-zA-Z_$][0-9a-zA-Z_$]*$

In English: It must start with a dollar sign, underscore or one of letters in the 26-character alphabet, upper or lower case. Subsequent characters (if any) can be one of any of those or a decimal digit.

JavaScript 1.5 and later * : ^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$

This is more difficult to express in English, but it is conceptually similar to the older syntax with the addition that the letters and digits can be from any language. After the first character, there are also allowed additional underscore-like characters (collectively called “connectors”) and additional character combining marks (“modifiers”). (Other currency symbols are not included in this extended set.)

JavaScript 1.5 and later also allows Unicode escape sequences, provided that the result is a character that would be allowed in the above regular expression.

Identifiers also must not be a current reserved word or one that is considered for future use.

There is no practical limit to the length of an identifier. (Browsers vary, but you’ll safely have 1000 characters and probably several more orders of magnitude than that.)

Links to the character categories:

  • Letters: Lu, Ll, Lt, Lm, Lo, Nl
    (combined in the regex above as “L”)
  • Combining marks (“modifiers”): Mn, Mc
  • Digits: Nd
  • Connectors: Pc

*n.b. This Perl regex is intended to describe the syntax only — it won’t work in JavaScript, which doesn’t (yet) include support for Unicode Properties. (There are some third-party packages that claim to add such support.)

danorton
  • 11,804
  • 7
  • 44
  • 52
  • 6
    It should be noted that your second regex has some false positives. [Supplementary Unicode characters](http://mathiasbynens.be/notes/javascript-encoding#bmp) (e.g. [U+2F800 CJK Compatibility Ideograph](http://graphemica.com/%F0%AF%A0%80), which is listed in the [Lo] category) are [disallowed in identifier names](http://mathiasbynens.be/notes/javascript-identifiers), as JavaScript interprets them as two individual surrogate halves (e.g. `\uD87E\uDC00`) which don’t match any of the allowed Unicode categories. Your regex, however, would allow such a character. Also, U+200C and U+200D are missing. – Mathias Bynens Mar 12 '12 at 09:20
  • 3
    ES6 formally defines valid identifiers using character classes meant expressly for this purpose (use in progamming) -- not sure if this was true previously -- meaning you can make an this regex slightly more readable, if not taking into account reserved words -- or at least it would be if it weren't for the fact that Unicode escape sequences are now valid in identifiers, too! This is exact according to the ES6 spec: (?:[\p{ID_Start}\$_]|\\u(?:[\dA-Fa-f]{4}|\{[\dA-Fa-f]+\}))([\p{ID_Continue}\$_\u200C\u200D]|\\u(?:[\dA-Fa-f]{4}|\{[\dA-Fa-f]+\}))* – Semicolon Apr 12 '15 at 21:57
14

Actually, ECMAScript says on page 15: That an identifier may start with a $, an underscore or a UnicodeLetter, and then it goes on (just below that) to specify that a UnicodeLetter can be any character from the Unicode categories, Lo, Ll, Lu, Lt, Lm and Nl. And when you look up those categories you will see that this opens up a lot more possibilities than just Latin letters. Just search for "Unicode categories" in Google and you can find them.

ƬƦƖƝƛ
  • 169
  • 1
  • 11
Yuvalik
  • 425
  • 3
  • 3
13

JavaScript Variables

You can start a variable with any letter, $, or _ character. As long as it doesn't start with a number, you can include numbers as well.

Start: [a-z], $, _

Contain: [a-z], [0-9], $, _

jQuery

You can use _ for your library so that it will stand side-by-side with jQuery. However, there is a configuration you can set so that jQuery will not use $. It will instead use jQuery. To do this, simply set:

jQuery.noConflict();

This page explains how to do this.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
EndangeredMassa
  • 17,208
  • 8
  • 55
  • 79
11

In case regular expressions is not a must, it would be better to just ask the browser to decide using eval:

function isValidVarName( name ) {
    try {
        // Update, previoulsy it was
        // eval('(function() { var ' + name + '; })()');
        Function('var ' + name);
    } catch( e ) {
        return false;
    }
    return true;
}

isValidVarName('my_var');     // true
isValidVarName('1');          // false
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anas Nakawa
  • 1,977
  • 1
  • 23
  • 42
11

The accepted answer would rule out a lot of valid identifiers, as far as I can see. Here is a regular expression that I put together which should follow the spec (see chapter 7.6 on identifiers). Created it using RegexBuddy and you can find an export of the explanation at http://samples.geekality.net/js-identifiers.

^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\u200C\u200D]*+$

In addition, the name cannot be one of the following reserved words.

break, do, instanceof, typeof, case, else, new, var, catch, finally, return, void, continue, for, switch, while, debugger, function, this, with, default, if, throw, delete, in, try, class, enum, extends, super, const, export, import, implements, let, private, public, yield, interface, package, protected, static, null, true, false

Svish
  • 152,914
  • 173
  • 462
  • 620
6

JavaScript variables can have letters, digits, dollar signs ($) and underscores (_). They can't start with digits.

Usually libraries use $ and _ as shortcuts for functions that you'll be using everywhere. Although the names $ or _ aren't meaningful, they're useful for their shortness and since you'll be using the function everywhere you're expected to know what they mean.

If your library doesn't consist on getting a single function being used everywhere, I'd recommend that you use more meaningful names as those will help you and others understand what your code is doing without necessarily compromising the source code niceness.

You could for instance take a look at the awesome DateJS library and at the syntactic sugar it allows without the need of any symbol or short-named variables.

You should first get your code to be practical, and only after try making it pretty.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Miguel Ventura
  • 10,344
  • 2
  • 31
  • 41
3

I wrote a glitch workspace that iterates over all the codepoints and emit the character if eval('var ' + String.fromCodePoint(#) + ' = 1') works.

It just keeps going, and going, and going....

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Allain Lalonde
  • 91,574
  • 70
  • 187
  • 238
1

Here is one quick suggestion for creating variable names.

If you want the variable not to conflict when being used in Firefox, do not use the variable name "_content" as this variable name is already being used by the browser. I found this out the hard way and had to change all of the places I used the variable "_content" in a large JavaScript application.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    Here is a jsfiddle that alerts when the variable "_content" is not "undefined" and when "_content" is set by FireFox, it is set to equal "window.content" http://jsfiddle.net/R2qvt/3/ – DanBrianWhite Feb 21 '14 at 20:50
1

I've taken Anas Nakawa's idea and improved it. First of all, there is no reason to actually run the function being declared. We want to know whether it parses correctly, not whether the code works. Second, a literal object is a better context for our purpose than var XXX as it's harder to break out of.

    function isValidVarName( name ) {
    try {
        return name.indexOf('}') === -1 && eval('(function() { a = {' + name + ':1}; a.' + name + '; var ' + name + '; }); true');
    } catch( e ) {
        return false;
    }
    return true;
}

// so we can see the test code
var _eval = eval;
window.eval = function(s) {
    console.log(s);
    return _eval(s);
}

console.log(isValidVarName('name'));
console.log(isValidVarName('$name'));
console.log(isValidVarName('not a name'));
console.log(isValidVarName('a:2,b'));
console.log(isValidVarName('"a string"'));

console.log(isValidVarName('xss = alert("I\'m in your vars executin mah scrip\'s");;;;;'));
console.log(isValidVarName('_;;;'));
console.log(isValidVarName('_=location="#!?"'));

console.log(isValidVarName('ᾩ'));
console.log(isValidVarName('ĦĔĽĻŎ'));
console.log(isValidVarName('〱〱〱〱'));
console.log(isValidVarName('जावास्क्रिप्ट'));
console.log(isValidVarName('KingGeorgeⅦ'));
console.log(isValidVarName('}; }); alert("I\'m in your vars executin\' mah scripts"); true; // yeah, super valid'));
console.log(isValidVarName('if'));
cleong
  • 7,242
  • 4
  • 31
  • 40
  • 1
    Don't even try. `isValidVarName('}; }); alert("I\'m in your vars executin\' mah scripts"); true; // yeah, super valid');` – 1j01 Jul 26 '15 at 20:36
  • 1
    @1j01, Agh, I forgot about code comment. I was hoping the unbalancing of brackets alone could keep code from running. A simple check for `}` should preclude that. – cleong Jul 27 '15 at 22:09
  • `isValidVarName("delete") === true` – 1j01 Jul 28 '15 at 15:26