这次学习 jQuery 源码,基于当前最新的版本,3.2.1。

IIFE

(function() {
'use strict';
//
})();

定义一个匿名函数并立即执行,得益于 javascript 奇葩的特性,只能据此模拟命名空间。

利用 IIFE 来建立命名空间需要 3 步( 《Web开发权威指南》 ):

  1. 如果命名空间已经存在,获取它的引用。

  2. 创建模块代码。

  3. 将模块代码绑定到命名空间上。

按照这个思路扩展下代码:

(function(window) {
'use strict'; var jQuery = window.jQuery || {}; // jQuery.xxx = xxx; window.jQuery = jQuery;
})(window);

自己的组件如此操作是可行的, jQuery 这样的库跟别的库、框架共用一个命名空间就很不合适了:

(function(window) {
'use strict'; var jQuery = function() {}; // 保存原有的命名,防止覆盖、冲突
var _jQuery = window.jQuery, _$ = window.$; // 把命名还回去
jQuery.noConflict = function(deep) {
if(window.$ === jQuery) {
window.$ = _$;
} if(deep && window.jQuery === jQuery) {
window.jQuery = _jQuery;
} return jQuery;
} window.jQuery = window.$ = jQuery; return jQuery;
})(window);

CommonJS 支持

要判断是否处于 CommonJS 规范相关的环境,只要判断 moduleexports 这些变量是否存在即可:

(function(global, factory) {
"use strict"; if (typeof module === "object" && typeof module.exports === "object") {
module.exports = factory(global);
} else {
factory(global);
} })(typeof window !== "undefined" ? window : this, function(window) {
'use strict'; var jQuery = function() {}; window.jQuery = window.$ = jQuery; return jQuery;
});

Node 采用的 CommonJS 模块规范,用 Node 写例子:

var jQuery = require('./jQuery');

console.log(jQuery);

运行可见,能如愿正确导出。

AMD 支持

(function(global, factory) {
"use strict"; if (typeof module === "object" && typeof module.exports === "object") {
module.exports = factory(global);
} else {
factory(global);
} })(typeof window !== "undefined" ? window : this, function(window) {
'use strict'; var jQuery = function() {}; if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
} );
} window.jQuery = window.$ = jQuery; return jQuery;
});

document

jQuery 归根结底是一个快捷操作 DOM 的库,换句话说,脱离了浏览器,就没啥用了。

浏览器环境,jQuery 是通过 document 属性来判断的。

这里面又分两种情况:

  1. 调用者本身就有 document 属性,则直接执行 factory,返回 jQuery
  2. 调用者本身没有 document 属性,返回一个带一个参数的函数,根据这个参数是否有 document 再处理。

另外,通过 CommonJS 模块化导出,并不需要把 jQuery 直接绑在调用者身上,直接返回就好了,修修补补后,最外层的骨骼就长这样:

(function(global, factory) {
"use strict"; if (typeof module === "object" && typeof module.exports === "object") {
module.exports = global.document ?
factory(global, true) :
function(w) {
if (!w.document) {
throw new Error("jQuery requires a window with a document");
}
return factory(w);
};
} else {
factory(global);
} })(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
'use strict'; var jQuery = function() {}; if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
} );
} var _jQuery = window.jQuery, _$ = window.$; jQuery.noConflict = function(deep) {
if(window.$ === jQuery) {
window.$ = _$;
} if(deep && window.jQuery === jQuery) {
window.jQuery = _jQuery;
} return jQuery;
} if ( !noGlobal ) {
window.jQuery = window.$ = jQuery;
} return jQuery;
});

后续

模块化的东西并不是 jQuery 的核心部分,也就追求个有就成,所以这系列的后续代码都是基于简化后的骨架来的:

(function(window) {
var jQuery = function() {}; window.jQuery = window.$ = jQuery;
})(window);

代码地址:

https://github.com/oldmanscode/jq_step_by_step/blob/master/step1.js

jQuery 最外面的那层皮的更多相关文章

  1. jquery弹出关闭遮罩层实例

    jquery弹出关闭遮罩层实例. 代码如下: <!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" & ...

  2. jQuery实现网页右下角悬浮层提示

    最近有同事提到类似网页右下角的消息悬浮提示框的制作.我之前也做过一个类似的例子,很简单.是仿QQ消息.现在感觉之前的那个例子只是说了实现原理,整体上给你的感觉还是太丑,今天为大家带来一个新的例子.是D ...

  3. jquery鼠标经过弹出层写法

    jquery鼠标经过弹出层写法<pre><div class="navitem"><a href="/index.php?c=news&am ...

  4. jQuery弹出深色系层菜单

    低调奢华jQuery弹出层菜单,使用新版的jQuery库,兼容多种浏览器.Demo展示: http://hovertree.com/texiao/layer/3/ 本特效可以作为网站的引导页,使用jQ ...

  5. jQuery弹出关闭遮罩层

    效果体验:http://keleyi.com/keleyi/phtml/jquery/9.htm 完整代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XH ...

  6. jquery图片放大镜和遮罩层效果

    图片放大镜效果将借助于jqzoom插件,遮罩层借助于thickbox插件. 1.引入样式表 /*整体样式*/ <link rel="stylesheet" href=&quo ...

  7. jQuery 插件开发——PopupLayer(弹出层)

    导读:上次写了一篇关于GridView的插件开发方法,上几天由于工作需要,花了一天左右的事件封装了popupLayer(弹出层)插件.今天有时间就记录一下自己的开发思想与大家分享下,同时也算是对这段时 ...

  8. jQuery点击弹出层,弹出模态框,点击模态框消失

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  9. Ajax -异步请求 -jquery中ajax分类 -第一层 $.ajax -第二层($.get /$.post) -第三层($.getJson/$.getScript) -相应演示

    Ajax 1.标准请求响应时浏览器的动作(同步操作) 1.1浏览器请求什么资源,跟随显示什么资源2.ajax:异步请求. 2.1局部刷新,通过异步请求,请求到服务器资源数据后,通过脚本修改页面中部分内 ...

随机推荐

  1. JQuery使用笔记

    1.选择器 id选择器: $('#btnShow') class选择器: $('.banner') tag选择器: $('input') 2.常用方法 取 / 设value: $('#btnShow' ...

  2. eclipse自定义代码模板

    eclipse自定义代码模板 Eclipse 提供了非常多的代码模板,我们可以通过 Windows->Preferences->Java->Editor->Templates ...

  3. 关于springboot启动的问题.

    IDE使用的是IDEA: 遇到的问题:使用springboot自带main方法无法启动示例,解决方案: 如果大家使用Application中的main方法无法正常启动时,可以去修改Project St ...

  4. 【深圳】大湾区第三次.NET技术交流会(网络直播)

    活动简介 云.devops.微服务.容器是现在这个发展阶段的软件形态, 本次活动我们围绕这些话题介绍.NET生态下的发展.SQL Server 2017可根据需要运行本地部署的SQL Server,当 ...

  5. spark2的编译

    0.操作系统 centos:6.4 hadoop:2.5.0-cdh5.3.6 1.为什么要编译 spark 源码? 学习spark的第一步 就应该是编译源码,后期修改和调试,扩展集成的功能模块 2. ...

  6. 2017计算机学科夏令营上机考试-A判决素数个数

    A:判决素数个数 总时间限制:  1000ms 内存限制:  65536kB 描述 输入两个整数X和Y,输出两者之间的素数个数(包括X和Y). 输入 两个整数X和Y(1 <= X,Y <= ...

  7. 自己动手实现mybatis动态sql

    发现要坚持写博客真的是一件很困难的事情,各种原因都会导致顾不上博客.本来打算写自己动手实现orm,看看时间,还是先实现一个动态sql,下次有时间再补上orm完整的实现吧. 用过mybatis的人,估计 ...

  8. Azure 基础:使用 Traffic Manager 分流用户请求

    为了减少 web 服务器的宕机时间,同时也提高服务器的响应性能,我们往往部署多个站点并通过负载均衡来对外提供服务.Azure 提供的 Traffic Manager 服务属于负载均衡的一种,特点是工作 ...

  9. 2017蓝桥杯省赛C/C++B(补题中)

    标题:等差素数列 2,3,5,7,11,13,....是素数序列. 类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列. 上边的数列公差为30,长度为6. 200 ...

  10. mysql分区分表

    为毛要分表和分区,,,,所有数据库的通病,文件越大,性能越低...那问题就来了.数据越多文件越大...无解?哎,所以说知道 为毛要分区了吧!那分表又是毛线?分表就是把一张表拆分成若干表,,,根据情况常 ...