jQuery 源码分析 核心代码结构

发布于 2021-07-31 11:45:51 字数 3109 浏览 1340 评论 0

前端的童鞋对 jQuery 绝对不会陌生,有不少刚入门的筒子,在不知 JS 为何物的时候,就已经在用 jQuery 了。这也应该归功于前端恶劣的生存环境:各自为政的浏览器厂商,依旧严峻的兼容性问题,并不好用的原生 API。

使用 jQuery 的理由有很多,喜欢它的理由也很多,优雅的接口,丰富的插件,完善的文档等。

jQuery 是什么

这里的 jQuery 指的并不是 jQuery 库,而是 jQuery 这个对象。首先用你习惯使用的编辑器打开jQuery-1.9.1.js,最好能够支持代码高亮和智能折叠。好家伙,源码加注释共 9500++ 行,怪吓人的。没错,这是每个有志学习jQuery源码的童鞋需要过的第一道坎。其实,完全没有必要害怕,将多余的噪音去掉,其实 jQuery 就是下面几行代码而已:

(function( window, undefined ) {
  var jQuery = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init( selector, context, rootjQuery );
  };
  window.jQuery = window.$ = jQuery;
})( window );

我们更为常用的符号$,其实就是 jQuery 的同名对象,而 jQuery 是个方法,它的作用是返回一个jQuery对象,更确切地来说,是jQuery.fn.init对象。

从一行熟悉的代码

$('#casper').addClass('handsome‘),从一行熟悉的代码说 jQuery 的核心源码结构,$('#casper').addClass('handsome‘) 这行代码的作用不用多说:给 ID 为 casper 的 dom 节点添加一个名为 handsome 的 class。很简单的一句代码,拆成两部分来看:

  • $('#casper') 返回一个jQuery对象,该对象的属性’0‘包含了选中的dom节点=> $('#casper')[0] === document.getElementById('casper')
  • .addClass('handsome') 给选中的dom节点添加handsome类,addClass为jQuery的prototype方法

于是我们把之前的那个简陋的骨架再丰满下,整个jQuery的骨架就基本出来了,里面的代码关键点在源码骨架后面会逐个进行讲解

源码骨架

(function( window, undefined ) {
var
  jQuery = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init( selector, context, rootjQuery );
  };

  //各种原型属性
  jQuery.fn = jQuery.prototype = {
    constructor: jQuery,
    init: function( selector, context, rootjQuery ) {
      //...
    },
    ...
  };
  jQuery.fn.init.prototype = jQuery.fn;

  //extend方法,用来扩展jQuery,或jQuery.fn
  jQuery.extend = jQuery.fn.extend = function() {
    //...
  };

  jQuery.fn.extend({
    addClass: function( value ) {
      //...
      return this;  //返回this,链式调用的秘密
    }
  });

  window.jQuery = window.$ = jQuery;

})( window );

return new jQuery.fn.init( selector, context, rootjQuery );

$('#casper') 跟 new $('#casper') 是一样的。个人觉得这里设计的原因,一个减少写一堆new的麻烦,同时也可以避免开发者不小心遗漏了 new 导致的诡异 bug。当然,不好的地方是,代码有点绕,这也算是jQuery源码的其中一个特点。

jQuery.fn = jQuery.prototype

没什么好讲,jQuery.prototype 为 jQuery 的原型方法,这里用 jQuery.fn 来代替 jQuery.prototype,只是为了少写几个字符,平常写插件时就是在这东东上面做修改

jQuery.fn.init.prototype = jQuery.fn

很好很绕的一个语句,上面说了 $(’#casper‘) 返回的其实是个jQuery.fn.init对象。所以,这里的作用,是让jQuery.fn上的方法都成为jQuery.fn.init对象的原型方法。
这个语句应该让很多刚接触jQuery源码的人感到困惑,包括我(=_=),可以试jQuery.fn.init.prototype.init.prototype.init...,如果你愿意可以一直写下去。

addClass: function( value ) {

下面这段代码很短很关键,别看它很简单,jQuery众多强大的接口就是这样通过jQuery.fn.extend一个一个扩展出来的,不赘述

jQuery.fn.extend({
  addClass: function( value ) {

写在后面

本文对 jQuery 源码核心结构进行了粗略的介绍,当然 jQuery 实际的源码要比这个复杂得多,但只要掌握了上面的要点,后续的分析就会轻松很多。 jQuery 源码之所以比较难看懂,是因为里面有许多为了解决糟糕的浏览器兼容性问题而引进的 hack。

万事开头难,这是笔者 jQuery 源码解析的开篇之作,网络上这类的文章很多,而且有些写的很不错,这里写作的原因,一来总结,二来备忘。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文