从jQuery源码理解jQuery插件的实现机制

基于jQuery源码学习jQuery中的插件实现机制,进一步加深对JS和Bootstrap中tooltip的理解。

--By Brisk Yu

(function( window, undefined ) {
    var jQuery = (function() {
        var jQuery = function( selector, context ) {
            return new jQuery.fn.init( selector, context, rootjQuery );
        }, 
     //。。。

     jQuery.fn
= jQuery.prototype = { constructor: jQuery, init: function(selector, context, rootjQuery){ //。。。 }, length: 0 //。。。 }; jQuery.fn.init.prototype = jQuery.fn; return jQuery; })(); window.jQuery = window.$ = jQuery; })(window);

首先学习jQuery 1.7 中的选择器实现源码。

(function( window,undefined ) {
 
})(window);

此处的function是一个匿名函数,可以理解为将window作为参数传递给function。function外的()的作用是让JS解释器将该条语句视为一个表达式[2]。JS解释器运行至此会执行function函数,并将函数执行的结果传给第二行的jQuery对象。undefined是Undefined类型唯一的值,此处作用是兼容不认识undefined的旧浏览器[1]。 

var jQuery = function( selector, context ) {
    return new jQuery.fn.init( selector, context, rootjQuery );
}

该函数实现jQuery的选择器功能,因此我们可以认为$('[data-toggle="tooltip"]')即是 new jQuery.fn.init( '[data-toggle="tooltip"]'), context, rootjQuery) ,将init函数实例化的对象传递给第三行的jQuery对象。这两个jQuery对象其实是一样的,第三行的jQuery对象会在最后当作方法的返回值传递给第二行的jQuery对象。

接下来,jQuery.fn.init方法体定义在:

jQuery.fn = jQuery.prototype = {
            constructor: jQuery,
            init: function(selector, context, rootjQuery){
                //实际生成jQuery对象的代码
            },
            length: 0
            //杂七杂八项
        };

在jQuery中,有且仅有函数具有prototype属性[3]当创建函数时,JS会为这个函数自动添加prototype属性,值是一个具有 constructor 属性的对象。而一旦将这个函数当作构造函数(constructor)调用(即通过new关键字调用),那么JS就会帮你创建该构造函数的实例,实例继承构造函数prototype的所有属性和方法[3]

jQuery.fn.init.prototype = jQuery.fn;

到这里思路就很清晰了,将 jQuery.fn与jQuery.fn.init的prototype对应。(暂时不太明白这样写的用意,可能是为了简化代码?)这样写完便可以在代码中用jQuery.fn来为init添加prototype。此时,如果我们向jQuery.fn添加函数时,其实便是向jQuery.fn.init的prototype添加该函数。因此init实例化后的对象便可以执行添加的函数。而末尾的window.jQuery = window.$ = jQuery方便我们可以在代码中用“$”来代替“jQuery”。

此时再看Bootstrap中tooltip实现的源码:

  $.fn.tooltip = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.tooltip')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

这里向jQuery对象的fn.init的prototype添加了一个tooltip属性,该属性指向一个方法。因此我们可以在JS中通过$('[data-toggle="tooltip"]').tooltip()打开提示框。

 

 

参考资料:

[1] https://blog.csdn.net/yanyan19880509/article/details/7339900

[2] https://swordair.com/function-and-exclamation-mark/

[3] https://github.com/creeperyang/blog/issues/9

posted @ 2018-09-07 15:55  Brisk  阅读(208)  评论(0编辑  收藏  举报