Quais caracteres são válidos para nomes de variáveis ​​JavaScript?

557

Quais caracteres podem ser usados ​​para nomear uma variável JavaScript?

Eu quero criar uma pequena "biblioteca de extensão" para meus usuários que não são JavaScript aqui no trabalho (que parecem todos sensíveis no que diz respeito ao idioma). Adoro como o jQuery e o Prototype usam o $cifrão e, como uso o jQuery, estou procurando outro símbolo de caractere único para usar.

Percebo que poderia testar vários caracteres, mas espero diminuir minha lista de caracteres (considerando a integração futura com outra biblioteca popular).

Richard Clayton
fonte
44
NÃO. Letras Unicode são aceitáveis. Experimente π, por exemplo.
N
14
Embora letras unicode sejam aceitáveis ​​em nomes de variáveis, o uso de código unicode pode ser problemático . Eu sugeriria não usá-los em nomes de variáveis ​​se você conseguir sobreviver sem eles.
Gary S. Weaver
F # é um nome de variável válido? Estou construindo uma pequena biblioteca javascript funcional e desejo usar o F # para o nome do módulo. Uma chamada de função típica ficaria assim: F # .partial (fn, ... presetArgs);
Jules Manson
@JulesManson Não, porque o símbolo da libra está reservado para outros usos.
Aidan Lovelace
@JulesManson A propósito, o nome F # já é usado pela Microsoft no .NET
Luke the Geek

Respostas:

986

Para citar nomes de variáveis ​​JavaScript válidos , minha redação resumindo as seções de especificações relevantes:

Um identificador deve começar com $, _ou qualquer caractere nas categorias Unicode "letra maiúscula (Lu)" , "letra minúscula (Ll)" , "letra de título em maiúsculas (Lt)" , "letra modificadora (Lm)" , "outra letra ( Lo) " ou " Número da letra (Nl) " .

O restante da sequência pode conter os mesmos caracteres, além de caracteres não marcadores de largura zero U + 200C , caracteres marcadores de largura zero U + 200D e caracteres nas categorias Unicode “Marca não espaçadora (Mn)” , “Combinação de espaçamento marca (Mc) ” , “ Número de dígito decimal (Nd) ” ou “ Pontuação do conector (PC) ” .

Também criei uma ferramenta que informará se qualquer sequência digitada é um nome de variável JavaScript válido de acordo com o ECMAScript 5.1 e Unicode 6.1:

Validador de nome de variável JavaScript


PS Para ter uma idéia de quão errada é a resposta de Anthony Mills: se você resumisse todas essas regras em uma única expressão regular somente para ASCII para JavaScript, seriam 11.236 caracteres . Aqui 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
fonte
31
Eu lhe darei crédito pelo tempo que você levou para gerar isso.
Richard Clayton
18
@marsbear Por acaso escrevi um artigo sobre isso também: mathiasbynens.be/notes/javascript-properties E uma ferramenta também: mothereff.in/js-properties#12e34 Aqui está uma resposta relevante do Stack Overflow .
Mathias Bynens
2
Caramba, então não posso ficar esperto e uso ¢para complementar $... oh bem ...)-:
hippietrail
3
É verdade (e uma resposta incrível). No entanto, isso não está certo: ocultar o código usando letras parecidas, mas de fato diferentes (ou usando letras que o ambiente não unicode NÃO pode usar) está errado, imo. Não ajudará na codificação e poderá criar inúmeros erros. A única boa vantagem: conscientizará as pessoas (dolorosamente) da possibilidade de que algum código use Unicode (e saiba muito sobre Unicode e suas diferentes representações) ... Sobre unicode: joelonsoftware.com/articles/Unicode.html
Olivier Dulac
4
@ n2liquid-GuilhermeVieira Somente se você assumir que todos os mecanismos JavaScript são 100% compatíveis com as especificações, o que nem sempre é o caso - certamente não foi quando eu fiz essa pesquisa. A postagem do blog que eu vinculei menciona todos os erros de navegador / mecanismo que arquivei e corrigi.
Mathias Bynens 19/03/2014
117

Na especificação ECMAScript na seção 7.6 Nomes e identificadores de identificador , um identificador válido é definido 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

o que cria muitas oportunidades para nomear variáveis ​​e também no golfe. Vamos tentar alguns exemplos.

Um identificador válido pode começar com qualquer um UnicodeLetter, $, _, ou \ UnicodeEscapeSequence. Uma letra unicode é qualquer caractere dessas categorias ( veja todas as categorias ):

  • Letra maiúscula (Lu)
  • Letra minúscula (Ll)
  • Letra em titlecase (Lt)
  • Letra modificadora (Lm)
  • Outra letra (Lo)
  • Número da letra (Nl)

Só isso explica algumas possibilidades malucas - exemplos de trabalho . Se não funcionar em todos os navegadores, chame-o de bug, pois deve.

var  = "something";
var ĦĔĽĻŎ = "hello";
var 〱〱〱〱 = "less than? wtf";
var जावास्क्रिप्ट = "javascript"; // ok that's JavaScript in hindi
var KingGeorge = "Roman numerals, awesome!";
Anurag
fonte
1
Você poderia copiar suas linhas de exemplo para esta página do Código Rosetta , que atualmente não possui um exemplo de JavaScript?
Walter Tross
73

Basicamente, na forma de expressão regular: [a-zA-Z_$][0-9a-zA-Z_$]*. Em outras palavras, o primeiro caractere pode ser uma letra ou _ ou $ e os outros caracteres podem ser letras ou _ ou $ ou números.

Nota: Embora outras respostas tenham apontado que você pode usar caracteres Unicode em identificadores JavaScript, a pergunta real era "Quais caracteres devo usar para o nome de uma biblioteca de extensões como o jQuery?" Esta é uma resposta para essa pergunta. Você pode usar caracteres Unicode nos identificadores, mas não o faça. As codificações são estragadas o tempo todo. Mantenha seus identificadores públicos no intervalo 32-126 ASCII, onde é seguro.

Anthony Mills
fonte
71
Eu provavelmente planejaria assassinar um co-desenvolvedor que usava caracteres unicode nos nomes de suas gravadoras. / discurso quase irônico
Erik Reppen
12
romkyns, não acho que "nomes de identificadores de caracteres Unicode" jamais sejam incluídos em "JavaScript: The Good Parts" e, como tal, prefiro ignorar a existência deles. No entanto, adicionei um aviso de isenção à minha resposta para seu benefício.
Anthony Mills
11
Em relação Encodings: por favor fazer personagens uso não-ASCII, pelo menos em suas strings literais. Temos que eliminar todo o software estúpido que faz com que as codificações sejam estragadas o tempo todo. Que felicidade simplesmente digitar Console.WriteLine("привет")C # e fazê-lo realmente funcionar !
Roman Starkov
14
Olha, @ Timwi, especialmente quando você está escrevendo uma biblioteca (como Richard diz que é), é gentil não forçar seus usuários a fazer besteira ou copiar e colar. Além disso, para o seu próprio material, você pode lidar bem com os aborrecimentos que surgem quando você encontra erros no navegador ou no servidor proxy ou o que quer que seja, mas fazer com que os usuários da sua biblioteca lidem com esse material não é legal. Uma boa resposta responde "o que devo fazer" mais do que apenas lidar com a pergunta em questão. Então, sim, eu quero ajudar as pessoas. Não incluirei as informações inúteis e perigosas, a menos que eu diga "ah, e não faça isso".
Anthony Mills
37
@Tchalvak Para código que você está usando, provavelmente está bem, usando Ʒ como o nome da biblioteca principal. (Ah, você pensou que era um 3? Desculpe, na verdade é U + 01B7 em maiúscula latina Ezh! Ou foi З, letra maiúscula cirílica Ze?) Se você estiver escrevendo uma biblioteca que pode ser usada por outras pessoas , no entanto, provavelmente é melhor seguir o ASCII.
Anthony Mills
18

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

Em inglês: deve começar com um cifrão, sublinhado ou uma das letras do alfabeto de 26 caracteres, maiúsculas ou minúsculas. Os caracteres subsequentes (se houver) podem ser um desses ou um dígito decimal.

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

Isso é mais difícil de expressar em inglês, mas é conceitualmente semelhante à sintaxe mais antiga, com a adição de que as letras e os dígitos podem ser de qualquer idioma. Após o primeiro caractere, também são permitidos caracteres adicionais do tipo sublinhado (coletivamente chamados de "conectores") e marcas adicionais de combinação de caracteres ("modificadores"). (Outros símbolos de moeda não estão incluídos neste conjunto estendido.)

O JavaScript 1.5 e posterior também permite seqüências de escape Unicode, desde que o resultado seja um caractere que seria permitido na expressão regular acima.

Identificadores também não devem ser uma palavra reservada atual ou que seja considerada para uso futuro.

Não há limite prático para o comprimento de um identificador. (Os navegadores variam, mas você terá 1000 caracteres com segurança e provavelmente várias mais ordens de magnitude que isso.)

Links para as categorias de personagens:

  • Cartas: Lu , Ll , Lt , Lm , Lo , Nl
    (combinadas no regex acima como "L")
  • Marcas combinadas (“modificadores”): Mn , Mc
  • Dígitos: Nd
  • Conectores: Pc

* nb Este regex Perl destina-se a descrever apenas a sintaxe - não funcionará em JavaScript, que ainda não inclui suporte para Propriedades Unicode. (Existem alguns pacotes de terceiros que pretendem adicionar esse suporte.)

danorton
fonte
Parece que não consigo fazer esse regex funcionar realmente. "test".match(/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/) === nullapesar de "teste" é um nome de variável JS válida
David Murdoch
Desculpe, mas o JavaScript não suporta este regex. Eu adicionei uma nota para esclarecer.
Danorton
5
Note-se que o seu segundo regex tem alguns falsos positivos. Caracteres Unicode suplementares (por exemplo, Ideógrafo de Compatibilidade U + 2F800 CJK , listado na categoria [Lo]) não são permitidos nos nomes dos identificadores , pois o JavaScript os interpreta como duas metades substitutas individuais (por exemplo \uD87E\uDC00) que não correspondem a nenhum Unicode permitido categorias. Sua regex, no entanto, permitiria esse personagem. Além disso, U + 200C e U + 200D estão ausentes.
Mathias Bynens 12/03/12
1
O ES6 define formalmente identificadores válidos usando classes de caracteres expressamente expressas para essa finalidade (uso na programação) - não tenho certeza se isso era verdade anteriormente - o que significa que você pode tornar esse regex um pouco mais legível, se não levar em consideração as palavras reservadas - ou pelo menos seria se não fosse o fato de que as seqüências de escape Unicode agora também são válidas nos identificadores! Isso é exato de acordo com a especificação do 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] + \})) *
Ponto
14

Na verdade, o ECMAScript diz na página 15: que um identificador pode começar com um $, um sublinhado ou um UnicodeLetter e depois continua (logo abaixo) para especificar que um UnicodeLetter pode ser qualquer caractere das categorias unicode, Lo, Ll , Lu, Lt, Lm e Nl. E quando você procurar essas categorias, verá que isso abre muito mais possibilidades do que apenas letras latinas. Basta procurar por "categorias unicode" no google e você pode encontrá-las.

Yuvalik
fonte
Erros de conexão e 404 são tudo o que recebo em todos os resultados relevantes ao pesquisar no ("categorias unicode") ... :(
Calmarius
13

Variáveis ​​Javascript

Você pode iniciar uma variável com qualquer letra $, ou_ caractere. Desde que não comece com um número, você também pode incluir números.

Começar: [a-z], $, _

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

jQuery

Você pode usar _a sua biblioteca para que ela fique lado a lado com o jQuery. No entanto, existe uma configuração que você pode definir para que o jQuery não seja usado $. Em vez disso, usará jQuery. Para fazer isso, basta definir:

jQuery.noConflict();

Esta página explica como fazer isso.

EndangeredMassa
fonte
Isso está absolutamente correto, mas eu dei a resposta a Anthony, que respondeu .02123413124 milissegundos antes de você. Desculpa.
Richard Clayton
8
@ Richard: Não, não está absolutamente correto. Veja as respostas de @Yuvalik e @ Anurag.
Tim Tim
@EndangeredMassa, por que usar a variável "_name"? por que não apenas nomear?
Tomasz Waszczyk
9

A resposta aceita excluiria muitos identificadores válidos , até onde posso ver. Aqui está uma expressão regular que eu montei, que deve seguir as especificações (consulte o capítulo 7.6 sobre identificadores). Criei usando o RegexBuddy e você pode encontrar uma exportação da explicação em http://samples.geekality.net/js-identifiers .

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

Além disso, o nome não pode ser uma das seguintes palavras 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, tente, classe, enum, estende-se, super, const, exportação, importação, implementa, deixe, privado, público, rendimento, interface, pacote, protegido, estático, nulo, verdadeiro, falso

Svish
fonte
Este regex não é um regex JS válido. Eu acho que você queria dizer: ^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\u200C\u200D]*$. Agora, mesmo com a correção, não consigo fazer com que esse regex funcione. "test".match(/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/) === nullmesmo que "test" seja um nome de variável JS válido
David Murdoch
Não, tenho certeza de que quis dizer o que escrevi :) A pergunta, como eu entendi, apenas perguntou o que é um nome de função javascript válido, não como um regex para isso seria especificamente em javascript. Eu fiz isso no RegexBuddy e estou usando no PHP na página de exemplo à qual vinculo. Funciona muito bem e testé aceito também.
Svish
3
@DavidMurdoch Escrevi uma expressão regular compatível com JavaScript de 11.335 caracteres que pode ser usada para validar identificadores (também conhecidos como nomes de variáveis). Veja minha resposta .
Mathias Bynens
3
@Ishish Note-se que o seu regex tem alguns falsos positivos. Caracteres Unicode suplementares (por exemplo, Ideógrafo de Compatibilidade U + 2F800 CJK , listado na categoria [Lo]) não são permitidos nos nomes dos identificadores , pois o JavaScript os interpreta como duas metades substitutas individuais (por exemplo \uD87E\uDC00) que não correspondem a nenhum Unicode permitido categorias. Sua regex, no entanto, permitiria esse personagem.
Mathias Bynens
2
@Svish Bem, sim, escrevendo as faixas mesmo, como eu fiz :) Note que seu regex também não leva em conta os eval, arguments, NaN, Infinitye undefinedcasos de ponta .
Mathias Bynens
6

As variáveis ​​Javascript podem ter letras, dígitos, cifrões ($) e sublinhados (_). Eles não podem começar com dígitos.

Normalmente, as bibliotecas usam $e _como atalhos para funções que você usará em qualquer lugar. Embora os nomes $ou_ não sejam significativos, eles são úteis devido à sua falta e, como você usará a função em todos os lugares em que espera saber o que eles significam.

Se sua biblioteca não consistir em usar uma única função em qualquer lugar, recomendo que você use nomes mais significativos, pois eles ajudarão você e outras pessoas a entender o que seu código está fazendo sem comprometer necessariamente a gentileza do código-fonte .

Você pode, por exemplo, dar uma olhada na incrível biblioteca DateJS e no açúcar sintático que ela permite, sem a necessidade de qualquer símbolo ou variável de nome abreviado .

Você deve primeiro fazer com que seu código seja prático e somente depois de tentar torná-lo bonito.

Miguel Ventura
fonte
4

caso as expressões regulares não sejam obrigatórias, não seria melhor pedir ao navegador para decidir 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
fonte
6
Não, não seria. xss = alert("I'm in your vars executin mah scrip's");;;;;por exemplo, não é um nome de variável javascript válido.
1j01 13/02/2014
6
xss;alert("try again");
1j01 14/02
1
É uma ideia bastante inteligente, apesar da vulnerabilidade de ataque do XSS.
Escova de dentes
@ 1j01 Como sobre a substituição namecom (typeof name === "string")? name.replace(/\(|\)/,"") : "_noXSS" )? Se for uma string, substituirá parênteses (definitivamente não é permitido em variáveis), então acho que executar qualquer coisa seria quase impossível.
Royhowie
2
Bem, então isValidVarName('aler(t')se torna verdade. E isValidVarName('_;;;')permanece verdadeiro. Mas você pode verificar no início se correspondesse algo como /[;,\(\)]/, mas depois você ainda pode executar _=location="#!?"para que você adicionar =à lista, mas você ainda pode executar '_\ndelete foo'(que passa o teste como um nome de variável válido) então você tem que excluir \ns e \rs e talvez alguma nova linha unicode? Mas `$` não é um identificador válido, então você deve excluir todos os espaços em branco ... É uma batalha perdida. Eu acho que é o mais longe que posso ir contra mim mesmo.if(/[;,\(\)=\s]/.exec(name))return!1
1j01 21/07
1

Aqui está uma sugestão rápida para criar nomes de variáveis. Se você deseja que a variável não entre em conflito ao ser usada no FireFox, não use o nome da variável " _content ", pois esse nome de variável já está sendo usado pelo navegador. Descobri isso da maneira mais difícil e tive que mudar todos os lugares em que usei a variável "_content" em um aplicativo JavaScript grande.

DanBrianWhite
fonte
Você pode provar isso com algum código-fonte que falha? Parece não fazer nada no Firefox.
Escova de dentes
Aqui está um jsfiddle que alerta quando a variável "_content" não é "indefinida" e quando "_content" é definida pelo FireFox, ela é igual a "window.content" jsfiddle.net/R2qvt/3
DanBrianWhite
1

Peguei a ideia de Anas Nakawa e a melhorei. Primeiro de tudo, não há razão para realmente executar a função que está sendo declarada. Queremos saber se ele analisa corretamente, não se o código funciona. Segundo, um objeto literal é um contexto melhor para o nosso propósito do var XXXque é mais difícil de sair.

    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
fonte
1
Nem tente. isValidVarName('}; }); alert("I\'m in your vars executin\' mah scripts"); true; // yeah, super valid');
1j01 26/07/2015
1
@ 1j01, Agh, esqueci o comentário do código. Eu esperava que apenas o desequilíbrio entre colchetes pudesse impedir a execução do código. Uma simples verificação }deve impedir isso.
cleong
isValidVarName("delete") === true
1j01
1

Escreveu um espaço de trabalho de falha que itera sobre todos os pontos de código e emite o caractere, se eval('var ' + String.fromCodePoint(#) + ' = 1')funcionar.

Apenas continua indo, indo e indo ....

Allain Lalonde
fonte