¿Qué caracteres son válidos para los nombres de variables de JavaScript?

557

¿Qué caracteres se pueden usar para nombrar una variable de JavaScript?

Quiero crear una pequeña "biblioteca de extensiones" para mis usuarios que no usan JavaScript aquí en el trabajo (que parecen ser aprensivos cuando se trata del lenguaje). Me encanta cómo jQuery y Prototype han usado el $signo de dólar, y dado que uso jQuery, estoy buscando otro buen símbolo de un solo carácter para usar.

Me doy cuenta de que podría probar una serie de caracteres, pero espero reducir mi lista de caracteres para empezar (en consideración a la futura integración con otra biblioteca popular, tal vez).

Richard Clayton
fuente
44
NO. Se aceptan letras Unicode. Pruebe π, por ejemplo.
nalply
14
Aunque las letras unicode son aceptables en los nombres de variables, el uso de unicode en el código puede ser problemático . Sugeriría no usarlos en nombres de variables si puedes sobrevivir sin ellos.
Gary S. Weaver
¿F # es un nombre de variable válido? Estoy construyendo una pequeña biblioteca de JavaScript funcional y deseo usar F # para su nombre de módulo. Una llamada de función típica se vería así: F # .partial (fn, ... presetArgs);
Jules Manson el
@JulesManson No, porque el símbolo de la libra está reservado para otros usos.
Aidan Lovelace
@JulesManson Por cierto, el nombre F # ya fue tomado por Microsoft de .NET
Luke the Geek

Respuestas:

986

Para citar nombres de variables válidos de JavaScript , mi escrito resume las secciones de especificaciones relevantes:

Un identificador debe comenzar con $, _o cualquier carácter en las categorías Unicode "Letra mayúscula (Lu)" , "Letra minúscula (Ll)" , "Letra de título (Lt)" , "Letra modificadora (Lm)" , "Otra letra ( Lo) " o " Número de letra (Nl) " .

El resto de la cadena puede contener los mismos caracteres, además de los caracteres sin unión de ancho cero U + 200C , los caracteres de unión con ancho cero U + 200D y los caracteres de las categorías Unicode "Marca sin separación (Mn)" , "Combinación de separación marca (Mc) " , " Número de dígito decimal (Nd) " o " Puntuación de conector (Pc) " .

También he creado una herramienta que le dirá si alguna cadena que ingrese es un nombre válido de variable de JavaScript de acuerdo con ECMAScript 5.1 y Unicode 6.1:

Validador de nombre de variable de JavaScript


PD: para darle una idea de cuán incorrecta es la respuesta de Anthony Mills: si tuviera que resumir todas estas reglas en una sola expresión regular ASCII solo para JavaScript, tendría una longitud de 11,236 caracteres . Aquí está:

// ES5.1 / Unicode 6.1
/^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|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
fuente
31
Le daré crédito por la cantidad de tiempo que debe haberle tomado para generar esto.
Richard Clayton
18
@marsbear Yo también escribí un artículo sobre eso: mathiasbynens.be/notes/javascript-properties y también una herramienta: mothereff.in/js-properties#12e34 Aquí hay una respuesta mía relevante para el desbordamiento de pila .
Mathias Bynens
2
Maldición, así que no puedo ser inteligente y usarlo ¢para complementar $... oh, bueno ...)-:
hippietrail
3
Es cierto (y una respuesta increíble). Sin embargo, esto no lo hace correcto: ofuscar código al usar letras de aspecto similar pero de hecho diferentes (o usando letras que el entorno no Unicode NO puede usar) es Incorrecto, en mi opinión. No ayudará a la codificación, y puede crear numerosos errores en su lugar. El único aspecto positivo: hará que las personas (dolorosamente) sean conscientes de esa posibilidad de que algún código use Unicode (y dolorosamente consciente de Unicode y sus diferentes representaciones) ... Acerca de unicode: joelonsoftware.com/articles/Unicode.html
Olivier Dulac
44
@ n2liquid-GuilhermeVieira Solo si asumes que todos los motores de JavaScript son 100% compatibles con las especificaciones, lo cual no siempre es el caso, seguro que no fue cuando hice esta investigación. La publicación de blog a la que vinculé menciona todos los errores del navegador / motor que presenté y parcheé.
Mathias Bynens
117

De la especificación ECMAScript en la sección 7.6 Nombres e identificadores de identificador , un identificador válido se define como:

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

lo que crea muchas oportunidades para nombrar variables y también en el golf. Probemos algunos ejemplos.

Un identificador válido podría comenzar con una cualquiera UnicodeLetter, $, _, o \ UnicodeEscapeSequence. Una letra unicode es cualquier carácter de estas categorías ( ver todas las categorías ):

  • Letra mayúscula (Lu)
  • Letra minúscula (ll)
  • Título de la letra (Lt)
  • Modificador de letra (Lm)
  • Otra letra (Lo)
  • Número de letra (Nl)

Esto solo explica algunas posibilidades locas: ejemplos de trabajo . Si no funciona en todos los navegadores, llámelo un error, porque debería hacerlo.

var  = "something";
var ĦĔĽĻŎ = "hello";
var 〱〱〱〱 = "less than? wtf";
var जावास्क्रिप्ट = "javascript"; // ok that's JavaScript in hindi
var KingGeorge = "Roman numerals, awesome!";
Anurag
fuente
1
¿Podría copiar sus líneas de ejemplo en esta página de Rosetta Code , que actualmente carece de un ejemplo de JavaScript?
Walter Tross
73

Básicamente, en forma de expresiones regulares: [a-zA-Z_$][0-9a-zA-Z_$]*. En otras palabras, el primer carácter puede ser una letra o _ o $, y los otros caracteres pueden ser letras o _ o $ o números.

Nota: Si bien otras respuestas han señalado que puede usar caracteres Unicode en identificadores de JavaScript, la pregunta real fue "¿Qué caracteres debo usar para el nombre de una biblioteca de extensiones como jQuery?" Esta es una respuesta a esa pregunta. Puede usar caracteres Unicode en los identificadores, pero no lo haga. Las codificaciones se arruinan todo el tiempo. Mantenga sus identificadores públicos en el rango ASCII 32-126 donde sea seguro.

Anthony Mills
fuente
71
Probablemente planearía asesinar a un desarrollador conjunto que usó caracteres Unicode en sus nombres de etiqueta. / discurso apenas irónico
Erik Reppen
12
romkyns, no creo que los "nombres de identificadores de caracteres Unicode" se incluyan en "JavaScript: The Good Parts", y como tal, prefiero ignorar su existencia. Sin embargo, he agregado un descargo de responsabilidad a mi respuesta para su beneficio.
Anthony Mills
11
Con respecto a las codificaciones: utilice caracteres que no sean ASCII, al menos en los literales de cadena. Tenemos que eliminar todo el estúpido software que hace que las codificaciones se "arruinen todo el tiempo". ¡Qué felicidad simplemente escribir Console.WriteLine("привет")C # y hacer que realmente funcione !
Roman Starkov
14
Mire, @Timwi, especialmente cuando está escribiendo una biblioteca (como Richard dice que es), es amable de no forzar a sus usuarios a la basura Alt-blah o copiar y pegar. Además, para sus propias cosas, puede estar bien lidiando con las molestias que surgen cuando se encuentra con errores del navegador o del servidor proxy o lo que sea, pero hacer que los usuarios de su biblioteca lidien con esas cosas no es genial. Una buena respuesta responde "qué debo hacer" más que solo lidiar con la pregunta en cuestión. Entonces sí, quiero ayudar a las personas. No voy a incluir información inútil y peligrosa, a menos que diga "oh, y no hagas esto".
Anthony Mills
37
@Tchalvak Para el código que está utilizando, probablemente esté bien, utilizando Ʒ como nombre de la biblioteca principal. (Oh, ¿pensaste que era un 3? ¡Lo siento, en realidad es U + 01B7 letra mayúscula latina Ezh! ¿O fue З, letra mayúscula cirílica Ze?) Si vas a escribir una biblioteca que podría ser utilizada por otras personas Sin embargo, probablemente sea mejor atenerse a ASCII.
Anthony Mills el
18

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

En inglés: debe comenzar con un signo de dólar, un guión bajo o una de las letras en el alfabeto de 26 caracteres, mayúsculas o minúsculas. Los caracteres posteriores (si los hay) pueden ser uno de esos o un dígito decimal.

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

Esto es más difícil de expresar en inglés, pero es conceptualmente similar a la sintaxis anterior con la adición de que las letras y los dígitos pueden ser de cualquier idioma. Después del primer carácter, también se permiten caracteres adicionales de subrayado (denominados colectivamente "conectores") y marcas de combinación de caracteres adicionales ("modificadores"). (Otros símbolos de moneda no están incluidos en este conjunto extendido).

JavaScript 1.5 y posterior también permite secuencias de escape Unicode, siempre que el resultado sea un carácter que se permitiría en la expresión regular anterior.

Los identificadores tampoco deben ser una palabra reservada actual o una que se considere para uso futuro.

No hay límite práctico para la longitud de un identificador. (Los navegadores varían, pero seguramente tendrá 1000 caracteres y probablemente varios órdenes de magnitud más que eso).

Enlaces a las categorías de personajes:

  • Letras: Lu , Ll , Lt , Lm , Lo , Nl
    (combinadas en la expresión regular anterior como "L")
  • Combinación de marcas ("modificadores"): Mn , Mc
  • Dígitos: Nd
  • Conectores: PC

* nb Esta expresión regular de Perl está destinada a describir únicamente la sintaxis: no funcionará en JavaScript, que (todavía) no incluye soporte para las propiedades Unicode. (Hay algunos paquetes de terceros que afirman agregar dicho soporte).

Danorton
fuente
Parece que no puedo hacer que esta expresión regular funcione realmente. "test".match(/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/) === nulla pesar de que "prueba" es un nombre de variable JS válido
David Murdoch
Lo sentimos, pero JavaScript no admite esta expresión regular. He agregado una nota para aclarar.
danorton 03 de
55
Cabe señalar que su segunda expresión regular tiene algunos falsos positivos. Los caracteres Unicode suplementarios (p. Ej ., El ideógrafo de compatibilidad U + 2F800 CJK , que figura en la categoría [Lo]) no están permitidos en los nombres de los identificadores , ya que JavaScript los interpreta como dos mitades sustitutas individuales (p \uD87E\uDC00. Ej. ) Que no coinciden con ninguna de las Unicode permitidas categorías. Su expresión regular, sin embargo, permitiría tal personaje. Además, faltan U + 200C y U + 200D.
Mathias Bynens
1
ES6 define formalmente identificadores válidos utilizando clases de caracteres destinadas expresamente para este propósito (uso en programación), no estoy seguro de si esto era cierto anteriormente, lo que significa que puede hacer que esta expresión regular sea un poco más legible, si no tiene en cuenta las palabras reservadas, o ¡al menos lo sería si no fuera por el hecho de que las secuencias de escape Unicode ahora también son válidas en los identificadores! Esto es exacto según la especificación ES6: (?: [\ 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
14

En realidad, ECMAScript dice en la página 15: que un identificador puede comenzar con un $, un guión bajo o un UnicodeLetter, y luego continúa (justo debajo de eso) para especificar que UnicodeLetter puede ser cualquier personaje de las categorías unicode, Lo, Ll , Lu, Lt, Lm y Nl. Y cuando busque esas categorías verá que esto abre muchas más posibilidades que solo letras latinas. Simplemente busque "categorías unicode" en google y podrá encontrarlas.

Yuvalik
fuente
Errores de conexión y 404's todo lo que obtengo por cada resultado relevante cuando busco en Google ("categorías unicode") ... :(
Calmarius
13

Variables Javascript

Puede comenzar una variable con cualquier letra $, o _carácter. Siempre que no comience con un número, también puede incluir números.

Comienzo: [a-z], $, _

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

jQuery

Puede usarlo _para su biblioteca para que se mantenga al lado de jQuery. Sin embargo, hay una configuración que puede establecer para que jQuery no se use $. En su lugar lo usará jQuery. Para hacer esto, simplemente configure:

jQuery.noConflict();

Esta página explica cómo hacer esto.

Massara en peligro de extinción
fuente
Esto es absolutamente correcto, pero le di la respuesta a Anthony que respondió .02123413124 milisegundos antes que usted. Lo siento.
Richard Clayton el
8
@ Richard: No, no es del todo correcto. Ver las respuestas de @Yuvalik y @ Anurag.
Tim Down
@EndangeredMassa ¿por qué usar la variable "_name"? ¿Por qué no solo nombrar?
Tomasz Waszczyk
9

La respuesta aceptada descartaría muchos identificadores válidos , por lo que puedo ver. Aquí hay una expresión regular que puse junto que debería seguir la especificación (ver capítulo 7.6 sobre identificadores). Lo creé usando RegexBuddy y puede encontrar una exportación de la explicación en http://samples.geekality.net/js-identifiers .

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

Además, el nombre no puede ser una de las siguientes palabras reservadas.

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

Svish
fuente
Esta expresión regular no es una expresión regular JS válida. Creo que quería decir: ^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\u200C\u200D]*$. Ahora, incluso con la corrección, parece que no puedo hacer que esta expresión regular funcione realmente. "test".match(/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/) === nulla pesar de que "prueba" es un nombre de variable JS válido
David Murdoch
No, estoy bastante seguro de que quise decir lo que escribí :) La pregunta, tal como lo entendí, solo preguntaba qué es un nombre de función de JavaScript válido, no cómo una expresión regular para eso estaría específicamente en JavaScript. Lo hice en RegexBuddy y lo estoy usando en PHP en la página de muestra a la que enlazo. Funciona muy bien y también testes aceptado.
Svish
3
@DavidMurdoch He escrito una expresión regular compatible con JavaScript de 11,335 caracteres que se puede usar para validar identificadores (también conocidos como nombres de variables). Mira mi respuesta .
Mathias Bynens
3
@Svish Cabe señalar que su expresión regular tiene algunos falsos positivos. Los caracteres Unicode suplementarios (p. Ej ., El ideógrafo de compatibilidad U + 2F800 CJK , que figura en la categoría [Lo]) no están permitidos en los nombres de los identificadores , ya que JavaScript los interpreta como dos mitades sustitutas individuales (p \uD87E\uDC00. Ej. ) Que no coinciden con ninguna de las Unicode permitidas categorías. Su expresión regular, sin embargo, permitiría tal personaje.
Mathias Bynens
2
@Svish Pues sí, escribiendo los rangos de sí mismo, como lo hice :) Tenga en cuenta que su expresión regular también no da cuenta de los eval, arguments, NaN, Infinityy undefinedcasos extremos .
Mathias Bynens
6

Las variables de Javascript pueden tener letras, dígitos, signos de dólar ($) y guiones bajos (_). No pueden comenzar con dígitos.

Por lo general, las bibliotecas usan $y _como accesos directos para funciones que usará en todas partes. Aunque los nombres $o _no son significativos, son útiles por su brevedad y dado que utilizará la función en todas partes, se espera que sepa lo que significan.

Si su biblioteca no consiste en usar una sola función en todas partes, le recomiendo que use nombres más significativos, ya que estos lo ayudarán a usted y a otros a comprender lo que está haciendo su código sin comprometer necesariamente la simplicidad del código fuente .

Podría, por ejemplo, echar un vistazo a la increíble biblioteca DateJS y al azúcar sintético que permite sin la necesidad de ningún símbolo o variables con nombres cortos .

Primero debe hacer que su código sea práctico, y solo después de intentar hacerlo bonito.

Miguel Ventura
fuente
4

en caso de que las expresiones regulares no sean obligatorias, ¿no sería mejor pedirle al navegador que decida usar 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
Anas Nakawa
fuente
66
No, no lo haría. xss = alert("I'm in your vars executin mah scrip's");;;;;por ejemplo, no es un nombre de variable javascript válido.
1j01
66
xss;alert("try again");
1j01
1
Es una idea bastante inteligente, a pesar de la vulnerabilidad de ataque XSS.
Cepillo de dientes
@ 1j01 ¿Qué hay de reemplazar namecon (typeof name === "string")? name.replace(/\(|\)/,"") : "_noXSS" )? Si es una cadena, reemplazará los paréntesis (definitivamente no está permitido en las variables), por lo que creo que ejecutar cualquier cosa sería casi imposible.
royhowie
2
Bueno, entonces se isValidVarName('aler(t')hace realidad. Y se isValidVarName('_;;;')mantiene fiel. Pero podría verificar al inicio si coincidía con algo como, /[;,\(\)]/pero aún puede ejecutar _=location="#!?"para agregar =a la lista, pero aún puede ejecutar '_\ndelete foo'(que pasa la prueba como un nombre de variable válido), por lo que debe excluir \nsy \rs y tal vez alguna nueva línea unicode? Pero `$` no es un identificador válido, por lo que debe excluir todos los espacios en blanco ... Es una batalla perdida. Creo que es lo más lejos que puedo ir en mi contraif(/[;,\(\)=\s]/.exec(name))return!1
1j01
1

Aquí hay una sugerencia rápida para crear nombres de variables. Si desea que la variable no entre en conflicto cuando se usa en FireFox, no use el nombre de la variable " _content " ya que el navegador ya está usando este nombre de variable. Descubrí esto de la manera difícil y tuve que cambiar todos los lugares en los que utilicé la variable "_contenido" en una gran aplicación de JavaScript.

DanBrianWhite
fuente
¿Puedes probar esto con algún código fuente que falla? No parece hacer nada en Firefox.
Cepillo de dientes
Aquí hay un jsfiddle que alerta cuando la variable "_content" no está "indefinida" y cuando Firefox establece "_content", es igual a "window.content" jsfiddle.net/R2qvt/3
DanBrianWhite
1

Tomé la idea de Anas Nakawa y la mejoré. En primer lugar, no hay ninguna razón para ejecutar realmente la función que se declara. Queremos saber si se analiza correctamente, no si el código funciona. Segundo, un objeto literal es un mejor contexto para nuestro propósito que var XXXporque es más difícil de romper.

    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
fuente
1
Ni siquiera lo intentes. isValidVarName('}; }); alert("I\'m in your vars executin\' mah scripts"); true; // yeah, super valid');
1j01
1
@ 1j01, Agh, olvidé el comentario de código. Esperaba que solo el desequilibrio de los corchetes pudiera evitar que el código se ejecute. Una simple verificación para }debería excluir eso.
cleong
isValidVarName("delete") === true
1j01
1

Escribió un espacio de trabajo de falla que itera sobre todos los puntos de código y emite el carácter si eval('var ' + String.fromCodePoint(#) + ' = 1')funciona.

Simplemente sigue y sigue y sigue ...

Allain Lalonde
fuente