jQuery和$的问题

12

我正在修改一些代码,其中包含很多jQuery,但我不确定某些jQuery语句的作用。

在jQuery代码的顶部有:

jQuery.noConflict

*1. 我理解这一点。但是接下来有一些代码:

<script type="text/javascript">
(function($) {

$(document).ready(function() {

    jQuery.fn.fixEmail = function() {
    {
   return $(this).each(function() {
       var $s = $(this);                  
           ...code...
        }
}
</script>

我知道jQuery被使用是因为它具有noConflict功能。那么$参数是什么?

*2. 在另一个函数中,他们使用了

<script type="text/javascript">
jQuery(function(){
    var $ = jQuery;
    var cc = {
        mode : 'teaser',
        featureVisible : true,
        $loader : '<p class="loadingAnimation"><img height="32" src="' +
                config.xoImgUrl +
                '/images/ajax-loader.gif" width="32" /></p>',
                ....more code...
            }
}
</script>

所以他们将$设置为来自noConflict的jQuery。但是为什么?他们不能只使用jQuery吗?

*3. 我想使用的插件是通过以下方式初始化的:

   var $j = jQuery.noConflict();
    var $ = {};
    $j(document).ready(function(){
        $j.history.init(pageload);
        $j("a[@rel='history']").click(function(){
            ...more code...
        });
    });

我理解noConflict是什么,但var $ = {}是什么意思?

4个回答

69

例子 1:

我认为你遗漏了一些代码:

(function($) {

$(document).ready(function() {

    jQuery.fn.fixEmail = function() {
    {
   return $(this).each(function() {
       var $s = $(this);                  
           ...code...
        }
}
)(jQuery); //This line was missing in your code. 

让我们稍微修改一下这段代码,以理解其中的含义。

function complicatedFunction($) {
          // the document.ready call goes here.
}

接下来,你会如何调用这个函数?

complicatedFunction(someObject);

在 complicatedFunction 函数内部,$ 指的是 someObject。同意吗?

如果你写:

complicatedFunction(jQuery);

在函数内部,$ 引用的是 jQuery 对象。所以,complicatedFunction 中的所有内容都可以使用 '$',就像一个普通的 jQuery 用户一样。

回到原始代码,如果我们决定不给这个函数命名,也就是使其匿名化,你可以将代码视为:

(function($) { })(jQuery);

你正在创建一个匿名函数,它接受一个名为$的参数。 你立即调用这个匿名函数,并将jQuery对象传递给它。 通过这种方式,你不会修改全局的$对象,但是你的匿名函数内的所有代码都可以像$一直可用一样工作。很酷,不是吗?:)
例子2:
jQuery(function(){
        var $ = jQuery;
        var cc = {
                mode : 'teaser',
                featureVisible : true,
                $loader : '<p class="loadingAnimation"><img height="32" src="' +
                                config.xoImgUrl +
                                '/images/ajax-loader.gif" width="32" /></p>',
                ....more code...
            }
});

与示例1类似,我没有看到这种编码风格。(我甚至不知道这是否可行)

无论如何,在传递给jQuery的匿名函数内部,您可以本地化使用$而不影响其他代码。

是的,他们可以简单地在所有地方使用jQuery对象,但那将非常冗长,不是吗?

示例3:

var $ = {};

上面一行定义了一个空对象,并将其分配给变量$。

这相当于执行以下操作:

var $ = new Object();

这类似于你可以使用两种不同的语法来定义数组。

var items = [];  //same as var items = new Array();

一点历史

请记住,'$'符号本身并没有什么特别之处,它只是一个像其他变量名一样的变量。在早期,人们使用document.getElementById编写代码。由于JavaScript区分大小写,在写document.getElementById时犯错误是很正常的。例如:Id的'i'要大写吗?by的'b'要大写吗?你懂的。由于函数在JavaScript中是一等公民,所以可以始终这样做:

var $ = document.getElementById; //避免使用document.getElementById!

当Prototype库出现时,他们将获取DOM元素的函数命名为'$'。几乎所有的JavaScript库都效仿了这个想法。Prototype还引入了$$函数,用于使用CSS选择器选择元素。

jQuery也采用了$函数,但扩展了它,使其接受各种类型的“选择器”来获取所需的元素。如果你已经在项目中使用Prototype并想要包含jQuery,那么你会遇到问题,因为'$'可能指代Prototype的实现或jQuery的实现。这就是为什么jQuery有noConflict选项,以便您可以在使用Prototype的项目中包含jQuery,并逐步迁移您的代码。我认为这是约翰部分非常聪明的举动! :)


说实话,这个答案太啰嗦了,离题也太多了。质量胜过数量。而且我不明白“我从未见过这种编码风格。(我甚至不确定这是否有效)”是什么意思。什么“编码风格”?为什么不能行? - Matti Virkkunen
Matti,OP在帖子中贴出了三个不同的代码示例。我已经对每一个进行了评论。我的意思是,在我读过/处理过的公共代码中,我没有看到第二个示例中使用的风格。 - SolutionYogi
在第二个例子中,您可以删除 var $ = jQuery; 部分,并将其设置为 jQuery(function($){。这只是一个想法。 - machineaddict
我使用了你提到的例子:var $ = document.getElementById; 并尝试将其用作 var myDiv = $("myDiv");,但是我得到了一个 TypeError: 'getElementById' called on an object that does not implement interface Document. error. 的错误。(我也尝试过 ($)("myDiv") 但是得到了相同的错误)。你能解释一下吗? - Bere
1
@Bere 请参考我的回答“为什么函数别名不起作用”?https://dev59.com/h3NA5IYBdhLWcg3wVcJx#1162192,了解为什么这种方法对您不起作用。 - SolutionYogi

4

1

你在那段代码结尾处是否漏掉了一些代码?通常的惯例是这样的:

jQuery.noConflict();

(function($){

$(document).ready(function() {

    jQuery.fn.fixEmail = function() {
    {
   return $(this).each(function() {
       var $s = $(this);                  
           ...code...
        }
}

})(jQuery);

注意底部,jQuery作为函数表达式的参数被传递,所以$等于jQuery,但仅在该函数表达式内部有效。

2

他们本可以使用jQuery,但他们可能依赖于复制/粘贴代码,这些代码使用$。

3

我会重构这些代码,使用类似#1中提到的约定。我不确定他们为什么要将$设置为一个对象,但这样做有点可疑。


0

这段代码有异味。他们是否在使用另一个JavaScript库?

  1. $通常是JQuery函数,但我相信Prototype也使用它。这可能是Prototype代码吗? 2:你说得对。至少我想不出有什么原因。 3:这会将{}重置为一个新对象。基本上取消了JQuery的作用。

0

我假设你已经看过这个使用jQuery与其他JS库了吗?我认为那个页面回答了你的问题(请参见页面底部的“引用魔法- jQuery快捷方式”部分)。

总结一下:

  1. 传递$是在函数块内使用jQuery而不永久覆盖它的一种方法。
  2. 我猜作者更喜欢简洁的$而不是jQuery。
  3. 这是在另一个块内吗?同样为了方便,我认为他们想要重复使用$而不永久覆盖它。

你发布的代码中使用不同的冲突避免机制有点不一致,所以如果你能够的话,你可能需要重构一下。


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