jQuery技术内幕:深入解析jQuery架构设计与实现原理. 2.2 总体结构

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介:

2.2 总体结构

构造jQuery对象模块的总体源码结构如代码清单2-1所示。

代码清单2-1 构造 jQuery 对象模块的总体源码结构

 16 (function( window, undefined ) {

        // 构造 jQuery 对象

 22    var jQuery = (function() {

 25       var jQuery = function( selector, context ) {

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

 28          },

              // 一堆局部变量声明

 97       jQuery.fn = jQuery.prototype = {

 98          constructor: jQuery,

 99          init: function( selector, context, rootjQuery ) { ... },

              // 一堆原型属性和方法

319       };

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

324       jQuery.extend = jQuery.fn.extend = function() { ... };

388       jQuery.extend({

              // 一堆静态属性和方法

892       });

955       return jQuery;

 957    })();

         // 省略其他模块的代码

9246     window.jQuery = window.$ = jQuery;

9266 })( window );

下面简要梳理下这段源码。

第16~9266行是最外层的自调用匿名函数,第1章中介绍过,当jQuery初始化时,这个自调用匿名函数包含的所有JavaScript代码将被执行。

第22行定义了一个变量jQuery,第22~957行的自调用匿名函数返回jQuery构造函数并赋值给变量jQuery,最后在第9246行把这个jQuery变量暴露给全局作用域window,并定义了别名$。

在第22~957行的自调用匿名函数内,第25行又定义了一个变量jQuery,它的值是jQuery构造函数,在第955行返回并赋值给第22行的变量jQuery。因此,这两个jQuery变量是等价的,都指向jQuery构造函数,为了方便描述,在后文中统一称为构造函数jQuery()。

第97~319行覆盖了构造函数jQuery()的原型对象。第98行覆盖了原型对象的属性constructor,使它指向jQuery构造函数;第99行定义了原型方法jQuery.fn.init(),它负责解析参数selector和context的类型并执行相应的查找;在第27行可以看到,当我们调用jQuery构造函数时,实际返回的是jQuery.fn.init()的实例;此外,还定义了一堆其他的原型属性和方法,例如,selector、length、size()、toArray()等。

第322行用jQuery构造函数的原型对象jQuery.fn覆盖了jQuery.fn.init()的原型对象。

第324行定义了jQuery.extend()和jQuery.fn.extend(),用于合并两个或多个对象的属性到第一个对象;第388~892行执行jQuery.extend()在jQuery构造函数上定义了一堆静态属性和方法,例如,noConflict()、isReady、readyWait、holdReady()等。

看上去代码清单2-1所述的总体源码结构有些复杂,下面把疑问和难点一一罗列,逐个分析。

1)为什么要在构造函数jQuery()内部用运算符new创建并返回另一个构造函数的实例?

通常我们创建一个对象或实例的方式是在运算符new后紧跟一个构造函数,例如,newDate()会返回一个Date对象;但是,如果构造函数有返回值,运算符new所创建的对象会被丢弃,返回值将作为new表达式的值。

jQuery利用了这一特性,通过在构造函数jQuery()内部用运算符new创建并返回另一个构造函数的实例,省去了构造函数jQuery()前面的运算符new,即我们创建jQuery对象时,可以省略运算符new直接写jQuery()。

为了拼写更方便,在第9246行还为构造函数jQuery()定义了别名$,因此,创建jQuery对象的常见写法是$()。

2)为什么在第97行执行jQuery.fn = jQuery.prototype,设置jQuery.fn指向构造函数jQuery()的原型对象jQuery.prototype?

jQuery.fn是jQuery.prototype的简写,可以少写7个字符,以方便拼写。

3)既然调用构造函数jQuery()返回的jQuery对象实际上是构造函数jQuery.fn.init()的实例,为什么能在构造函数jQuery.fn.init()的实例上调用构造函数jQuery()的原型方法和属性?例如,$('#id').length和$('#id').size()。

在第322行执行jQuery.fn.init.prototype = jQuery.fn时,用构造函数jQuery()的原型对象覆盖了构造函数jQuery.fn.init()的原型对象,从而使构造函数jQuery.fn.init()的实例也可以访问构造函数jQuery()的原型方法和属性。

4)为什么要把第25~955行的代码包裹在一个自调用匿名函数中,然后把第25行定义的构造函数jQuery()作为返回值赋值给第22行的jQuery变量?去掉这个自调用匿名函数,直接在第25行定义构造函数jQuery()不也可以吗?去掉了不是更容易阅读和理解吗?

去掉第25~955行的自调用匿名函数当然可以,但会潜在地增加构造jQuery对象模块与其他模块的耦合度。在第25~97行之间还定义了很多其他的局部变量,这些局部变量只在构造jQuery对象模块内部使用。通过把这些局部变量包裹在一个自调用匿名函数中,实现了高内聚低耦合的设计思想。

5)为什么要覆盖构造函数jQuery()的原型对象jQuery.prototype?

在原型对象jQuery.prototype上定义的属性和方法会被所有jQuery对象继承,可以有效减少每个jQuery对象所需的内存。事实上,jQuery对象只包含5种非继承属性,其余都继承自原型对象jQuery.prototype;在构造函数jQuery.fn.init()中设置了整型属性、length、selector、context;在原型方法.pushStack()中设置了prevObject。因此,也不必因为jQuery对象带有太多的属性和方法而担心会占用太多的内存。

关于构造函数、原型、继承等基础知识,请查阅相关的基础类书籍。

相关文章
|
3天前
|
存储 算法 安全
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
10 0
|
2天前
|
数据采集 存储 API
Python虚拟环境数据共享技术解析:最佳实践与常见误区
本文探讨了Python爬虫开发中如何在虚拟环境中管理数据,提倡使用共享目录、数据库和API进行数据共享。通过创建虚拟环境、安装依赖并提供一个使用代理IP爬取微博数据的示例,阐述了如何配置代理、解析网页及保存数据到共享路径。强调了避免硬编码路径、忽视依赖管理和数据安全性的误区。
25 11
Python虚拟环境数据共享技术解析:最佳实践与常见误区
|
2天前
|
传感器 存储 数据采集
振弦采集仪的技术解析和应用进行详细介绍
振弦采集仪的技术解析和应用进行详细介绍
振弦采集仪的技术解析和应用进行详细介绍
|
2天前
|
传感器 数据采集 安全
工程安全监测中的振弦采集仪技术解析与应用
工程安全监测中的振弦采集仪技术解析与应用
工程安全监测中的振弦采集仪技术解析与应用
|
1天前
|
存储 安全 数据安全/隐私保护
移动APP安全加固技术深度解析
【7月更文挑战第12天】移动APP安全加固技术是保障移动应用安全的重要手段。通过对Android和iOS两大主流平台的安全加固,可以有效防止逆向分析、动态调试、数据篡改等安全威胁。在实际应用中,我们需要结合静态层面、动态层面和数据层面的加固技术,全方位地提升APP的安全性。同时,随着技术的不断发展,我们也需要不断关注新的安全威胁和加固技术,确保移动应用的安全性和稳定性。
|
1天前
|
编解码 前端开发 图形学
【技术深度解析】多平台适配下的UI适配难题:U3D游戏UI错乱的终极解决方案
【7月更文第12天】随着移动设备市场的多元化,Unity游戏开发者面临的一大挑战是如何在不同分辨率和屏幕尺寸的设备上保持UI的一致性和美观性。游戏在高分辨率平板与低分辨率手机上呈现出的UI布局混乱、按钮错位等问题,严重影响玩家体验。本文旨在探讨Unity UI(UGUI)在多平台适配中的最佳实践,通过优化Canvas Scaler设置、灵活运用RectTransform和Anchor Points,以及高效利用设计工具,确保UI的完美适配。
6 1
|
2天前
|
传感器 数据采集 安全
工程监测仪器振弦采集仪的技术解析与应用介绍
振弦采集仪的技术解析与应用进行介绍
工程监测仪器振弦采集仪的技术解析与应用介绍
|
2天前
|
运维 Kubernetes 监控
深入解析微服务架构的演进与实践
本文旨在探究微服务架构从诞生到成熟的发展历程,分析其背后的技术推动力和业务需求,并结合具体案例,揭示实施微服务过程中的挑战与解决策略。通过对微服务架构与传统单体架构的对比,阐明微服务如何优化现代应用开发流程,提高系统的可扩展性、可维护性和敏捷性。
11 0
|
2天前
|
缓存 图形学 UED
U3D开发技术深度解析:异步场景加载与资源管理优化策略
【7月更文第11天】在Unity3D(简称U3D)游戏开发中,优化场景加载与资源管理是提升用户体验的关键一环。通过实现高效的异步场景加载和智能的资源管理策略,我们能显著缩短玩家的等待时间,提升游戏流畅度。本文将详细介绍这两种技术的应用,并提供实用的代码示例。
7 0
|
5天前
|
机器学习/深度学习 人工智能 自然语言处理
人工智能、机器学习、深度学习:技术革命的深度解析(二)
人工智能、机器学习、深度学习:技术革命的深度解析(二)
10 0

推荐镜像

更多