Javascript/jQuery变量,使用var的正确方法是什么?

4

如果这是一个愚蠢或者简单的问题,我很抱歉,因为我对Javascript/jQuery还比较陌生。过去的一个月里,我开始深入了解脚本编写,并且发现人们在Javascript/jQuery中使用var的方式有两种,甚至三种。

我使用var的方式如下:

var nav = $('nav');

nav.hide();

我常见的一种人们使用变量的方式是:

var nav = $('nav');

$(nav).hide();

从这些答案中可以看出,

var $nav = $('nav');

$nav.hide();

从我通过谷歌搜索学到的知识来看,你在变量中输入的内容将被保存以备后用。当我使用$()包围var时,我认为它会复制$()。然而,两种方法似乎都可以工作,所以我知道它不会重复,并且可以确定它是相同的东西。
使用变量是否有正确的方式,还是两种方式都一样,不要紧?
如果有人能向我展示原始问题,我再次道歉,如果这是一个已知的答案,我会很高兴删除它,但我找不到任何关于这个问题的东西。
一个没有标记为答案,但我发现非常重要的答案。
var element = document.createElement("div");
$("body").append(element);
$(element).hide(); 

在上面的例子中,$(element)是必需的,因为它将DOM对象转换为jQuery选择器。jQuery函数只能在jQuery选择器上工作,所以你不能简单地使用element.hide()。

由于编写jQuery的简便性,我更熟悉它,并且完全理解jQuery是基于JavaScript的。幸运的是,我现在正在上JavaScript课程,这应该会有所帮助。 :D - Josh Powell
出于好奇,他们是否做得正确?(我现在严格使用*nix,所以我对微软的后期操作系统和/或浏览器几乎没有经验)我意识到它们更接近(并在某些领域领先),但是“正确”吗?真的吗..? - David Thomas
@DavidThomas 我完全同意微软还没有进入状态。他们可能正在尝试更多,但我不认为这可以弥补多年来让每个开发人员生活都变成地狱的错误。 - Josh Powell
1
感谢所有帮助过我的人,我非常感激你们花费的时间来帮助我!! - Josh Powell
IE9是朝着正确方向迈出的重要一步。IE10更进一步,而IE11正在真正起步,事实上我敢说IE11目前已经超越了Chrome。这可能有点大胆,但只需看看我的CSS就能知道。到处都是“-webkit-”前缀,但一个“-ms-”前缀也没有。 - Niet the Dark Absol
显示剩余2条评论
6个回答

9

$()创建一个新的jQuery对象。如果你将一个jQuery对象保存到变量中,那么从它再次创建另一个jQuery对象是没有意义的,尽管这样仍然可以工作。你经常会看到人们将先前创建为jQuery对象的变量包装在$()中,纯粹是由于不良实践和要么忘记它已经是一个对象...要么根本不理解他们第一次创建了什么。

也许你已经见过

var $nav = $('nav');

$nav.hide();

在代码中为了可读性,使用$前缀来表示该变量是jQuery对象是一个常见的做法。


嗯,我能看出这样做的好处,所以在以后维护代码时使用$nav会是最好的方法? - Josh Powell
4
@JoshPowell - 我不会去探讨什么是最佳的方法。这是一个偏好和观点的问题。使用任何对你有效的有效代码即可。 - j08691
非常感谢!我会继续按照自己的方式进行,而且我从这个问题中学到了很多! - Josh Powell

4

这两个变量都存储了一个 jQuery 对象,可以使用 jQuery 方法。后一种方式不必要地试图将该 jQuery 对象重新包装成另一个 jQuery 对象。前一种方式是“正确”的,因为它更高效、更少地冗余。


是的,说实话,我很困惑为什么有人会像那样使用变量,因为对我来说这似乎非常冗余。 - Josh Powell

3
我在很多地方都见过这个问题。人们在不必要的情况下使用了大量的$符号。有些人只是将它用作变量名上的装饰,这增加了混淆度。
首先,没有jQuery变量,只有JavaScript变量,正如你所说,变量存储信息。当右侧以$()开头时,您正在将jQuery函数的结果存储在变量中。在绝大多数情况下,您将存储的内容称为jQuery选择器。
var nav = $('nav')的情况下,您正在存储一个表示DOM中所有是nav标记(即类似于<nav></nav>或等价的)的元素的选择器。
正如其他人已经提到的那样,$(nav)正在使用存储的选择器,并从中创建一个新的选择器。它毫无意义且是多余的,是一种糟糕的编程习惯,即使它是普遍存在的。
但是,有一个类似的语法是有意义的:
var element = document.createElement("div");
$("body").append(element);
$(element).hide(); 

在上面的示例中,$(element)是必要的,因为它将DOM对象转换为jQuery选择器。 jQuery函数仅适用于jQuery选择器,因此您不能简单地执行element.hide()
正如我在开头提到的那样,有些人还在变量名上使用$作为修饰符,例如var $selector = $("nav")。左侧的$没有任何意义 - 它只是变量名中的一个字符,但他们将其用作惯例,以提醒自己他们正在存储一个jQuery选择器。 我会避免使用它,因为它会增加混乱,但是它确实存在,所以我想提一下。

1
是的,我看到迄今为止有两个回答者喜欢使用$前缀。我不使用它。我们将不得不在这个问题上达成一致。:-)(虽然我经常将变量命名为divSelector之类的东西,所以我可以看出$div是一个很好的简写。但我不接受它,因为已经有太多$了。) - Scott Mermelstein

2
var 用于创建任何类型的变量。可以是 var diceRoll = 4var myMessage = "Hello!",或其他任何东西。 $ 是 jQuery 提供的一个函数,其行为取决于您传递给它的内容。例如,如果您将字符串(例如 'nav')传递给它,它将在文档中查找每个 nav 元素并返回一组 jQuery 对象(元素) - 对于它找到的每个 DOM 元素都有一个。当您说 var nav = $('nav'); 时,您正在将这组 jQuery 对象分配给您的 nav 变量,以便稍后使用它。到目前为止还好。
不要将字符串传递给 $,您技术上可以将 jQuery 对象传回 $ 函数中,这就是您在说 $(nav).hide(); 时所做的。这样做没有意义 - 它只会返回您最初放入其中的相同的 jQuery 对象数组 nav!! 个人而言,我喜欢在保存 jQuery 对象的任何变量前加上 $ 符号,即 var $nav = $('nav');。这只是一种约定,让我一眼就能看出此变量保存了 jQuery 对象(元素),而不是本地 DOM 元素、整数等等。如果我在代码中看到 $($myVar),我知道可能是睡觉的时间了... 更新:除了字符串之外,还有其他事情可以传递到 $() 函数中。例如传递 DOM 元素(如说 $(document))会创建该 DOM 元素的 jQuery 对象表示,这非常有用。

解释并不十分准确,直到将DOM元素作为参数传递给$()之后,它才成为jQuery对象。 - charlietfl
@charlietfl 我认为我已经清楚地表明了这一区别:$ 将在文档中查找每个导航元素并返回一组jQuery对象(元素)-每个DOM元素一个。我哪里有歧义,以便我可以纠正它?谢谢。 - Shai

2
所有这些答案都是整个答案的一部分……让我再添加另一个部分。 :)
正如其他人所说,$(...) 表示一个 JQuery 函数,返回一个 JQuery 对象。取决于 "..." 是什么,决定了如何完成它。
一些例子:
- 如果你放一个选择器,比如 "div",你会得到一个包含所有匹配选择器模式的 DOM 元素的 JQuery 对象……在这种情况下,所有的 <div> 元素。 - 如果你传递一个 HTML 元素的字符串表示形式(例如,"<div></div>"),你会得到一个指向新创建的 <div> 元素的 JQuery 对象。 - 如果你把一个 DOM 节点引用放进去(例如,使用 document.getElementsByTagName("div") 创建的节点),它将创建一个指向该引用中的节点的 JQuery 对象。
整个目的是 JQuery 使用 JQuery 对象,因此这些各种函数帮助程序员创建它们。
现在我们来回答你的问题...
每次你使用 `$(“...”)` ,你都会创建一个全新的对象,所以例如下面的代码将产生两个唯一的 JQuery 对象,每个对象都指向相同的 DOM 元素:
var $firstObject = $("div");
var $secondObject = $("div");

所以,如果你对它们进行比较(例如这样($firstObject === $secondObject)),它们将不被视为相等,因为它们不是同一个对象。
现在,让我稍微改变一下你的第二个例子,以使其更加清晰。如果你创建一个第三个变量并将其设置为与第二个变量相等,就像这样:
var $thirdObject = $secondObject;

“你有两个元素实际上指向同一个 JQuery 对象,因此它们实际上是相等的(即($secondObject === $thirdObject)将评估为 true)。
现在最后,你展示了这段代码:”
$(nav).hide();

这是尝试创建另一个 JQuery 对象的另一个示例。这次使用另一个 JQuery 对象。然而,如果使用我上面创建的第三个变量来执行此操作,将会打破它与第二个变量之间的关系。($secondObject === $($thirdObject)),它们不再相等,因为比较的两侧不再指向同一个对象。就像前面比较 $firstObject 和 $secondObject 一样,该比较也使用了两个唯一的 JQuery 对象。
然而...
与其他答案不同,我认为这不是完全错误的编码形式。虽然我不会在您提供的示例中使用它,但将一个 JQuery 对象传递到 $(...) 函数中基本上与使用 .clone() 相同。下面的两个 $bar 分配在功能上是等效的:
var $foo = $("<div></div>");

var $bar = $($foo);
var $bar = $foo.clone();

JQuery API甚至也表达了同样的观点(http://api.jquery.com/jQuery/):

克隆jQuery对象

当将一个jQuery对象传递给$()函数时,会创建该对象的一个克隆。这个新的jQuery对象引用与初始对象相同的DOM元素。

编辑:

出于好奇,我在jsPerf上进行了快速测试,发现在Firefox、IE9和Chrome中,$($foo)方法比.clone()方法要快得多:http://jsperf.com/clone-technique-test


哇,那个测试显示了一些惊人的性能差异,非常感谢你的努力! - Josh Powell

1
var nav = $('nav');

$(nav).hide();

nav 已经是一个 jQuery 对象,因此 $(nav) 是无用的。


这就是我想到的,因为我已经在变量中写了$(),但我看到很多答案或代码函数都像第二个例子一样有var。我最初认为这是浪费额外的打字,但我一遍又一遍地看到它。 - Josh Powell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接