记录本人学习源码的,学习心得和理解
温馨提示:这篇文章已超过489天没有更新,请注意相关的内容是否还可用!
本篇简介
本系列是拿来记录本人学习源码的,学习的版本是v2.1.4。目的有两个,一是记录学习的过程,二是分享学习经验和理解。学习jq源码的原因呢,虽然目前有了像vue,react,ng这种的现代前端框架,但是jq的设计观念是永不过时的,所以我就想去探究探究。
整体结构
近万行的代码,如果直接看的话,可能会没有模式php jquery源码分析,抽解后的结构大概如下:
(function(global, factory) {
//判断module 判断导出方式
factory(global);
}(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
// 定义一些私有变量
// init
// extend
// extend functions
// sizzle
// callbacks
// deferred
// data
// dom css attr
// event
// ajax
// animation
return jQuery
}))
复制代码
后面的函数体是被一个马上执行函数包裹着的,这样设计的目的一目了然,就是为了避免变量体里的代码污染全局的代码,也避免了外面的代码更改外部的方式,除了暴露的接口。
把内部通过及时执行函数传给外部好处是不应该去找全局的,方便压缩,在外部被压缩成w。把一个工厂函数传入立即执行变量,让外部判断导出方法并执行变量。
工厂函数外部,是把功能组件进行了分离,让架构变得井然有序,分成了软件组件、选择器模块、回调函数管理组件、延迟对象模块,数据管理组件、事件模块、ajax、动画和css、属性模块。
在工厂函数的最终一行把对象返回了出来。
初始化构造函数
在工厂函数第一段先是定义了一些变量
var arr = [];
var slice = arr.slice;
var concat = arr.concat;
var push = arr.push;
...
var version = "2.1.4",
jQuery = function (selector, context) {
return new jQuery.fn.init(selector, context)
}
...
复制代码
定义一些原生数组和对象的方式那样的设计是为了便于管控和便利压缩php jquery源码分析,原理同上。下面也定义了几个软件函数去空格、加兼容、转驼峰等,这里面最重要的一个步骤是这个函数。
jQuey函数接受两个参数,一个选取器,一个上下文。返回的是一个例子对象,可以看出,这是通过.fn.init()构造出来的,真正的构造函数是.fn.init()。
.fn=.={}
jQuery.fn = jQuery.prototype = {
jquery: version,
constructor: jQuery,
...
toArray: function () {
return slice.call(this);
},
get(){...},
each(){...},
map(){...},
...
}
复制代码
这一段代码是覆盖了的原型,由于覆盖了原型,所以要更改构造器的指向:,如果不改实例化后就是指向。然后下降版本属性,添加一些常用的转数组,slice、push、sort、、map等方式在原型对象上。
这种设计的好处可能是调用或$的之后就手动实例化了,方便操作和链式调用。
init方法是在内部给原型上添加的(源码第2765行):
var init = jQuery.fn.init = function (selector, context) {...}
复制代码
内部就是判定是否合法:
if (!selector) return this;
if (typeof selector === "string") {
...
} else if (selector.nodeType) {
...
} else if (jQuery.isFunction(selector)) {
...
}
复制代码
init.prototype = jQuery.fn;
复制代码
这一句代码是直接实例化的关键。
这种设计后可以直接实例化以及拥有上的所有方式。
插件和扩展一些软件方式
jQuery.extend = jQuery.fn.extend = function () {... return target;}
复制代码
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
复制代码
的作用是向原本添加静态方式以及向原型添加方法。这种通过扩展的形式来添加方式,可以让架构更可控。
源码的实现,先是做了判断:
// 是否是深拷贝
if (typeof target === "boolean") {
deep = target;
target = arguments[i] || {};
i++;
}
// 不是对象和函数就赋值成对象
if (typeof target !== "object" && !jQuery.isFunction(target)) {
target = {};
}
// 只有一个参数
if (i === length) {
target = this;
i--;
}
复制代码
如果存在多个对象的话:
for (; i < length; i++) {
if (target === copy) { continue; } // 防止循环引用
if () {} // 深拷贝
else if () {} // 浅拷贝
}
复制代码
如果要看这个细致实现的话在源码的第176行
添加静态方式(源码第241行)
添加了error,,,,,,grep等十几个软件方式,这里就不做细致讲解了。
总结
这一篇的话就讲了大概的架构和初始化,下一篇中将讲解回调事件管理和延迟对象管理,将学习到观察体系和事件队列的观念。
本文来自网络,如有侵权请联系网站客服进行删除
还没有评论,来说两句吧...