【问题标题】:I am not able to understand how jQuery chaining works [closed]我无法理解 jQuery 链接是如何工作的 [关闭]
【发布时间】:2012-09-25 14:49:38
【问题描述】:

我无法理解 jQuery 链接的工作原理。

jQuery("div").attr("id", "_id")
    .hide()
    .show();

我做了类似链接的事情,但我不确定它是否与 jQuery 使用的逻辑相同。

var fun = (function (parma) {
return function () {
    return {
        start: function () {
            console.log("start");
            return this;
        },

        mid: function () {
            console.log("mid");
            return this;
        },

        last: function () {
            console.log("last");
            return this;
        }
    }
}

})();

// Working
fun().start()
    .mid()
    .last();

【问题讨论】:

  • 这里没有问题...
  • "Yes" 是答案的缩写,所以我将其作为评论发布:-)

标签: jquery javascript javascript-framework unobtrusive-javascript


【解决方案1】:

如果函数的返回值是具有方法的对象,则可以立即调用该方法。就这么简单。

由于您返回this,因此您返回的对象与调用前一个方法的对象相同。这意味着您将返回一个具有所有相同方法的对象。


这样想:

var f = {
    foo: function() {
             console.log("foo");
             return b;
         }
};

var b = {
    bar: function() {
             console.log("bar");
             return f;
         } 
};

这里我们有两个对象。

  • f 对象有一个名为 foo 的方法,该方法返回 b 对象。
  • b 对象有一个名为 bar 的方法,该方法返回 f 对象。

因此,在调用foo之后,我们可以调用bar,反之亦然。

f.foo().bar().foo().bar(); // etc

但是因为f 没有barb 没有foo,所以我们永远不能调用同一个方法两次。


但是如果我们只有一个对象,它有两种方法,而且两种方法总是返回相同的原始对象呢?

var fb = {
    foo: function() {
             console.log("foo");
             return fb;
         },
    bar: function() {
             console.log("bar");
             return fb;
         }
};

现在我们总是返回一个同时具有 foobar 方法的对象,因此我们可以调用其中任何一个方法。

fb.foo().bar().bar().bar().foo().foo().bar();

所以现在唯一真正的区别是我们返回fb 而不是this,但这并不重要,因为它们是同一个对象。上面的代码可以做return this;,它的行为是一样的。

如果您想创建对象的多个实例,这很重要,但这是面向对象技术的问题,而不是方法链接

【讨论】:

  • 这解释了单例中的链接,但这根本不是 jQuery 的工作原理。
  • @David:原型继承是 jQuery 将方法与它创建的对象关联起来的方式。这与链接无关。 jQuery 的链接是通过返回this 来完成的,它是对调用上下文对象的引用。链接或返回 this 不需要原型继承。
  • 嗯,问题是关于“jQuery 链接如何工作”,而不是一般的链接。
  • @David:我的第二句话回答了这个问题。 OP 所做的就是 jQuery 所做的。方法如何附加到对象与链接无关。没有“jQuery 链接”之类的东西。
【解决方案2】:

每个函数上的return 都是一个jQuery 对象。每个 jQuery 对象都会引用所有函数,例如show/hide,所以你可以简单地写

jQuery("#myDiv")         //returns a jQuery object 
    .attr("id", "_id")   //sets the ID and returns the jQuery object
    .hide()              //Hides the element with ID myDiv and returns jQuery object
    .show();             //show the element with ID myDiv and returns jQuery object

【讨论】:

    【解决方案3】:

    这样想:

    var myLib = {
        foo: function() {
            alert("FOO!");
            return this;
        },
        bar: function() {
            alert("BAR!");
            return this;
        }
    }
    
    myLib.foo().bar();
    

    jQuery 并不完全像这样做,但这是获得链接功能的一种方法。这个特定的不存储有关当前对象的信息。

    jQuery 对象具有返回修改后的 jquery 对象的方法,允许您在其上调用更多方法。

    【讨论】:

      【解决方案4】:

      如果我没记错的话,jQuery 使用一种经典的方法在其原型中进行链接,但有一个例外,它的 init 原型中还有一个 enhanced 构造函数。这是一个简单的模式:

      function myQuery(elem){
         return new myQuery.prototype.init(elem);
      };
      
      myQuery.prototype.init = function(elem) { // the constructor "enhanced"
          this.elem = elem;
      };
      
      // now copy the myQuery prototypes into init.prototype
      myQuery.prototype.init.prototype = myQuery.prototype;
      
      // here comes the chainable prototypes:
      
      myQuery.prototype.start = function() {
          this.elem.className = 'start';
          return this; // returning the instance allows further chaining
      };
      
      myQuery.prototype.finish = function() {
          this.elem.className = 'finish';
          return this;
      };
      
      // now use it
      myQuery(document.body).start().finish();
      

      链接原型更有效,因为您可以为每个实例重用原型方法。 jQuery 经常在一个文档中被初始化很多次,如果你每次创建一个包含所有可链接方法的新对象,都会增加不必要的开销和可能的泄漏。

      【讨论】:

      • “链接原型更有效,因为您可以为每个实例重用原型方法。” jQuery 只是返回一个通过原型继承获取其方法的对象。原型设计与链接的有效性无关。 “链接原型”实际上没有任何意义。
      【解决方案5】:

      几乎每个 jQuery 函数也会返回一个 jQuery 对象。因此,您可以在每个返回的对象上运行 jQuery 函数。

      通过编写链式代码,您不仅可以节省时间,还可以提高性能。在不强制计算机寻找和使用特定节点的情况下,对返回的对象进行操作比启动另一个实例要高效得多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-21
        • 2021-12-28
        • 2021-12-15
        • 1970-01-01
        相关资源
        最近更新 更多