jQuery 源码分析 核心代码结构

发布于 2021-07-31 11:45:51 字数 3109 浏览 1346 评论 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

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

文章
评论
84963 人气
更多

推荐作者

微信用户

文章 0 评论 0

小情绪

文章 0 评论 0

ゞ记忆︶ㄣ

文章 0 评论 0

笨死的猪

文章 0 评论 0

彭明超

文章 0 评论 0

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