关于命名约定:为什么JavaScript变量以美元符号开头?

Why would a JavaScript variable start with a dollar sign?

我经常看到以美元符号开头的变量的javascript。什么时候/为什么选择以这种方式给变量加前缀?

(我不是问jquery和其他语言中的$('p.foo')语法,而是像$name$order这样的普通变量)


jquery中的一个非常常见的用途是将存储在变量中的jquery对象与其他变量区分开来。例如,我将定义

1
2
var $email = $("#email"); // refers to the jQuery object representation of the dom object
var email_field = $("#email").get(0); // refers to the dom object itself

我发现这对于编写jquery代码非常有用,并且可以很容易地看到具有不同属性集的jquery对象。


在ECMAScript的第1版、第2版和第3版中,规范明确不鼓励使用带$-前缀的变量名,除非在自动生成代码的上下文中:

The dollar sign ($) and the underscore (_) are permitted anywhere in an identifier. The dollar sign is intended for use only in mechanically generated code.

但是,在下一个版本(第5版,即当前版本)中,这个限制被取消,上面的段落被替换为

The dollar sign ($) and the underscore (_) are permitted anywhere in an IdentifierName.

因此,$符号现在可以在变量名中自由使用。某些框架和库在符号含义上有自己的约定,在这里的其他答案中也提到了这一点。


正如其他人所提到的,美元符号旨在被机械生成的代码使用。然而,这种约定已经被一些广受欢迎的JavaScript库打破了。jquery、prototype和ms-ajax(aka-atlas)都在它们的标识符中使用这个字符(或者作为一个完整的标识符)。

简而言之,您可以随时使用$。(翻译不会抱怨)问题是你想什么时候用?

我个人不使用它,但我认为它的使用是有效的。我认为MS Ajax使用它来表示函数是一些更详细的调用的别名。

例如:

1
var $get = function(id) { return document.getElementById(id); }

这似乎是一个合理的惯例。


在AngularJS的上下文中,$前缀仅用于框架代码中的标识符。要求框架的用户不要在自己的标识符中使用它:

Angular Namespaces $ and $$

To prevent accidental name collisions with your code, Angular prefixes names of public objects with $ and names of private objects with $$. Please do not use the $ or $$ prefix in your code.

资料来源:https://docs.angularjs.org/api


我是2006年发起这项大会的人,并在早期的jquery邮件列表中推广了它,所以让我来分享一下它的一些历史和动机。

接受的答案给出了这个例子:

1
2
var $email = $("#email"); // refers to the jQuery object representation of the dom object
var email_field = $("#email").get(0); // refers to the dom object itself

但这并不能很好地说明这一点。即使没有$,这里仍然有两个不同的变量名,emailemail_field。那就足够了。当我们已经有两个不同的名字时,为什么我们需要在其中一个名字中加入一个$

实际上,我在这里不会使用email_field,原因有两个:names_with_underscores不是惯用的javascript,field对dom元素没有真正意义。但我也有同样的想法。

我尝试了一些不同的东西,其中一些与示例非常相似:

1
2
var email = $("#email"), emailElement = $("#email")[0];
// Now email is a jQuery object and emailElement is the first/only DOM element in it

(当然,jquery对象可以有多个dom元素,但是我正在处理的代码中有很多id选择器,因此在这些情况下有1:1的对应关系。)

我还有一个例子,一个函数接收到一个dom元素作为参数,还需要一个jquery对象:

1
2
3
4
5
// email is a DOM element passed into this function
function doSomethingWithEmail( email ) {
    var emailJQ = $(email);
    // Now email is the DOM element and emailJQ is a jQuery object for it
}

好吧,这有点令人困惑!在我的一段代码中,email是jquery对象,emailElement是dom元素,而在另一段代码中,email是dom元素,emailJQ是jquery对象。

没有一致性,我一直把它们混在一起。另外,为了同一件事,必须用两个不同的名称来组合,这有点麻烦:一个用于jquery对象,另一个用于匹配的dom元素。除了emailemailElementemailJQ之外,我也一直在尝试其他的变体。

然后我注意到一个常见的模式:

1
2
var email = $("#email");
var emailJQ = $(email);

由于javascript将$视为名称的另一个字母,而且由于我总是从$(whatever)调用中得到jquery对象,所以这种模式最终让我明白了。我可以接一个$(...)的电话,只需删除一些字符,就会得到一个很好的名字:

1
2
<wyn>$<del>("#</del>email<del>")</del></wyn>
<wyn>$<del>(</del>email<del>)</del></wyn>

删除不完美,但您可能会想到:删除某些字符后,这两行的结尾看起来都像:

1
$email

那时候我意识到我不需要像emailElementemailJQ这样的约定。已经有一个很好的惯例在盯着我看:从一个$(whatever)的电话里拿出一些字符,它就变成了$whatever

1
2
var $email = $("#email"), email = $email[0];
// $email is the jQuery object and email is the DOM object

还有:

1
2
3
4
5
6
// email is a DOM element passed into this function
function doSomethingWithEmail( email ) {
    var $email = $(email);
    // $email is the jQuery object and email is the DOM object
    // Same names as in the code above. Yay!
}

所以我不必一直编两个不同的名字,只需使用同一个名字加上或不加$前缀。$前缀是一个很好的提示,提醒我正在处理一个jquery对象:

1
$('#email').click( ... );

或:

1
2
3
var $email = $('#email');
// Maybe do some other stuff with $email here
$email.click( ... );

Stevo是对的,美元脚本符号(在javascript和jquery平台中,但在php中)的含义和用法是完全语义的。$是可以用作标识符名称的一部分的字符。此外,美元符号可能不是您在JavaScript中可以遇到的最"奇怪"的事情。以下是一些有效标识符名称的示例:

1
2
3
4
var _       = function() { alert("hello from _"); }
var \u0024  = function() { alert("hello from $ defined as u0024"); }
var ?       = function() { alert("hello from ?"); }
var $$$$$   = function() { alert("hello from $$$$$"); }

上面所有的例子都可以。

试试看。


对于javascript引擎,$字符没有特殊意义。它只是变量名中的另一个有效字符,如a-z、a-z、u0-9等…


正如我在过去4年中所经历的,它将允许一些人轻松地识别指向值/对象的变量或jquery包装的dom元素

1
2
3
4
5
Ex:
var name = 'jQuery';
var lib = {name:'jQuery',version:1.6};

var $dataDiv = $('#myDataDiv');

在上面的示例中,当我看到变量"$dataDiv"时,我可以很容易地说这个变量指向jquery包装的dom元素(在本例中是div)。另外,我还可以调用所有jquery方法,同时不再包装对象,比如$dataDiv.append()、$dataDiv.html()、$dataDiv.find(),而不是$($dataDiv.append()。

希望能有所帮助。所以最后要说的是,遵循这一点是一个很好的实践,但不是强制性的。


由于在变量名的开头使用_来表示一个私有变量(或者至少有一个打算保持私有),我发现$便于在我自己的简短别名前面添加到通用代码库中。

例如,在使用jquery时,我更喜欢使用变量$J,而不是仅使用$,在使用php.js等时使用$P

前缀使其在视觉上与其他变量(如我自己的静态变量)不同,包括代码是某个库或其他库的一部分,并且一旦知道约定,就不太可能与其他变量冲突或混淆。

它也不会使代码混乱(或者需要额外的输入),就像为每个库调用重复一个完全指定的名称一样。

我喜欢把它想象成类似于修改键在扩展单个键的可能性方面所做的工作。

但这只是我自己的惯例。


${varname}只是jquery开发人员用来区分保存jquery元素的变量的命名约定。

普通的{varname}用于存储文本和字符串等一般信息。${varname}保存jquery返回的元素。

您也可以使用plain {varname}来存储jquery元素,但是正如我在开始时所说的,这将它与普通变量区别开来,并使其更容易理解(想象一下,将它混淆为普通变量,然后搜索所有内容来理解它所包含的内容)。

例如:

1
var $blah = $(this).parents('.blahblah');

这里,blah正在存储返回的jquery元素。

所以,当其他人看到代码中的$blah时,他们会理解它不仅仅是字符串或数字,而是jquery元素。


虽然您可以简单地使用它作为标识符的前缀,但它应该用于生成的代码,例如模板中的替换标记。


角度用途是用于框架生成的属性。猜猜看,他们是按照ECMA-2623.0提供的提示(现在已经失效)。


$用于在常规变量的情况下区分公共变量和jquery变量。让您在Flipkart中下订单,然后如果订单是一个显示字符串输出的变量,那么它被命名为简单的"订单",但是如果我们单击"下订单",则返回一个对象,该对象将用$表示为"$order",这样程序员就可以截取整个代码中的javascript变量和jquery变量。


如果您看到美元符号($)或双美元符号($),并且对原型框架中这意味着什么感到好奇,那么下面是您的答案:

1
2
3
4
5
6
7
8
$$('div');
// -> all DIVs in the document.  Same as document.getElementsByTagName('div')!

$$('#contents');
// -> same as $('contents'), only it returns an array anyway (even though IDs must be unique within a document).

$$('li.faux');
// -> all LI elements with class 'faux'

来源:http://www.prototypejs.org/api/utility/dollar-dollar


有效的javascript标识符shuold必须以字母开头,下划线(u)或美元符号($);后续字符也可以是数字(0-9)。因为javascript区分大小写,信件包括字符"A"到"Z"(大写)和字符"a"到"z"(小写)。

细节:https://developer.mozilla.org/en-us/docs/web/javascript/guide/grammar_和_类型变量


我有时将PHP名称约定与JavaScript变量一起使用的原因是:在进行输入验证时,我希望在客户端运行完全相同的算法,以及服务器端。我真的希望代码的两面看起来尽可能相似,以简化维护。在变量名中使用美元符号使这变得容易。

(此外,一些明智的助手函数有助于使代码看起来类似,例如包装输入值查找、strlen的非oo版本、substr等。不过,它仍然需要一些手动调整。)