哪些字符可以用来命名JavaScript变量?

我想为工作中的非javascript用户创建一个小型的“扩展库”(当涉及到这种语言时,他们似乎都很拘谨)。我喜欢jQuery和Prototype都使用$ dollar符号,因为我使用jQuery,所以我正在寻找另一个很好的单字符符号来使用。

我意识到我可以只测试一些字符,但我希望缩小字符列表的范围(考虑到未来可能与另一个流行库集成)。


当前回答

如果正则表达式不是必须的,最好是让浏览器决定使用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

其他回答

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

在英语中:必须以美元符号、下划线或26个字符中的一个字母开头,大写或小写。后续字符(如果有)可以是这些字符中的任意一个,也可以是十进制数字。

JavaScript 1.5及以后*:^ [\ p {L} \ p{问}$ _][\ p {L} \ p{问}$ \ p {Mn} \ p {Mc} \ p{和}\ p{电脑}]*美元

这在英语中更难以表达,但它在概念上类似于旧的语法,只是字母和数字可以来自任何语言。在第一个字符之后,还允许有额外的类似下划线的字符(统称为“连接符”)和额外的字符组合标记(“修饰符”)。(其他货币符号不包括在这个扩展集。)

JavaScript 1.5及更高版本还允许Unicode转义序列,前提是结果是在上述正则表达式中允许的字符。

标识符也不能是当前的保留字,也不能是将来使用的保留字。

标识符的长度没有实际限制。(浏览器各不相同,但你可以拥有1000个字符,甚至更多数量级。)

字符类别的链接:

字母:Lu, Ll, Lt, Lm, Lo, Nl(在上述正则表达式中合并为“L”) 组合符号(“修饰语”):Mn, Mc 数字:Nd 连接器:电脑


*注意。这个Perl正则表达式仅用于描述语法——它在JavaScript中不起作用,因为JavaScript(目前)还不支持Unicode属性。(有一些第三方软件包声称添加了这种支持。)

基本上,以正则表达式形式:[a-zA-Z_$][0-9a-zA-Z_$]*。换句话说,第一个字符可以是字母、_或$,其他字符可以是字母、_、$或数字。

注意:虽然其他回答指出可以在JavaScript标识符中使用Unicode字符,但实际的问题是“我应该使用什么字符作为像jQuery这样的扩展库的名称?”这就是那个问题的答案。您可以在标识符中使用Unicode字符,但不要这样做。编码总是被搞砸。将公共标识符保持在32-126 ASCII范围内,这样比较安全。

在ECMAScript规范第7.6节的标识符名称和标识符中,一个有效的标识符定义为:

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

这为命名变量创造了很多机会,在高尔夫运动中也是如此。我们来举几个例子。

有效的标识符可以以UnicodeLetter、$、_或\ UnicodeEscapeSequence开头。Unicode字母是以下类别中的任何字符(请参阅所有类别):

大写字母(Lu) 小写字母(Ll) 头衔信(Lt) 修饰字母(Lm) 其他字母(Lo) 字母编号(Nl)

仅这一点就说明了一些疯狂的可能性-工作的例子。如果它不能在所有浏览器中工作,那么就称它为bug,因为它应该是bug。

var ᾩ = "something";
var ĦĔĽĻŎ = "hello";
var 〱〱〱〱 = "less than? wtf";
var जावास्क्रिप्ट = "javascript"; // OK, that's JavaScript in Hindi
var KingGeorgeⅦ = "Roman numerals, awesome!";

据我所知,公认的答案将排除许多有效的标识符。下面是一个符合规范的正则表达式(参见7.6章关于标识符)。使用RegexBuddy创建它,您可以在http://samples.geekality.net/js-identifiers上找到解释的导出。

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

且名称不能为以下保留字。

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

下面是创建变量名的一个快速建议。

如果您希望变量在Firefox中使用时不发生冲突,请不要使用变量名“_content”,因为该变量名已被浏览器使用。我发现这一点很困难,不得不在一个大型JavaScript应用程序中更改所有使用变量“_content”的地方。