Zepto源码分析之一(代码结构及初始化)
关于读源码,读jQuery自然是不错,但太过于庞大不易解读,对于小白,最好从Zepto,Lodash这样的小库入手。
这里使用的是zepto1.1.6版本为例。
自执行函数
在阅读之前,先弄清楚闭包和自执行函数
两种方式: (function() {})() 和 (function() {}())
(function() {
console.log('这里直接执行')
})()
(function () {
console.log('这里直接执行')
}())
自执行函数的优势在于,避免了全局变量的污染,即在自执行函数体内声明的变量,外部是无法访问到的。
(function () {
let val = '123'
})()
console.log(val) // val is not defined
如需要获取变量val的值,只能在函数体内部返回,然后将函数赋值给一个全局变量
let temp= (function () {
let val = '123';
return val; // 必须return, 否则获取不到值
})()
window.temp = temp;
console.log(temp) //
而关于闭包,简单理解就是在自执行函数内部声明变量或方法,在自执行函数内就形成了一个闭合的上下文环境,外部是无法直接访问的。
源码结构
;let Zepto = (function () {
let $, zepto = {};
return $; // 最终返回值
})()
window.Zepto = Zepto;
window.$ === undefined && (window.$ = Zepto);
首先声明一个字支持函数并赋给变量Zepto, 再将变量Zepto赋给全局变量window.Zepto
如果$未被声明,则也将Zepto赋给window.$全局变量
此时,外部访问Zepto或者$都可以返回自执行函数内部的$(即 return $)
再看$到底是什么
$返回一个函数,传入的参数是selector选择器(即tagName,id,或className),context暂为空。
;let Zepto = (function () {
let $, zepto = {};
$ = function(selector, context) {
console.log('获取节点');
return zepto.init(selector, context);
};
return $;
})();
window.Zepto = Zepto;
window.$ === undefined && (window.$ = Zepto);
此时,如果访问节点, 会输出'获取节点'
<div>
<span>测试</span>
<span>测试</span>
<span>测试</span>
</div>
let span = $('span');
console.log(span)


这里报错是因为init方法还未定义;
继续创建 init方法
init函数是绑定在zepto对象上的方法(之前已经声明一个zepto空对象)
zepto.init = function(selector, context) {
let dom;
// 处理dom的代码
return zepto.Z(dom, selector);
};
init处理dom部分,分为几种情况
1 . 当不传参数 $(), 直接返回zepto.Z()不传参
if (!selector) return zepto.Z()
2 . 当传入字符串参数,又分为几种
else if (typeof selector == 'string') {
selector = selector.trim()
if (selector[0] == '<' && fragmentRE.test(selector))
dom = zepto.fragment(selector, RegExp.$1, context), selector = null
else if (context !== undefined) return $(context).find(selector)
else dom = zepto.qsa(document, selector) //这里的qsa其实就是document.querySelectorAll()
}
(1) $(' span ')
首先将清除字符串前后空格 selector.trim()
(2) $('<div></div>')
如果第一个字符是<,并且正则fragmentRE成立,
则使用fragment方法处理dom节点
if (selector[0] == '<' && fragmentRE.test(selector))
dom = zepto.fragment(selector, RegExp.$1, context), selector = null

(3) $('span', 'div')
如果传入第二个参数,即之前的context不等于undefined,则相当于执行$('div').find('span')
else if (context !== undefined) return $(context).find(selector)
若div中存在span则返回span,否则返回空数组。
(4)如以上三种不满足则执行最后一步,zepto.qsa()

3 . 如果传入函数,用document调用一个zepto对象,然后$.ready()方法, ready方法和上面的find方法一样在后面创建。
else if (isFunction(selector)) return $(document).ready(selector);
4 . 若已经是一个zepto对象,则直接返回该对象,不必再调用$(), 即 $($('span')) === $('span')
else if (zepto.isZ(selector)) return selector
zepto.isZ = function(object) {
return object instanceof zepto.Z
}
5 . 若是引用类型
else {
// 如参数是数组,则调用compact方法, 会将null或undefined剔除
if (isArray(selector)) dom = compact(selector)
// 如是DOM节点,则数组化
else if (isObject(selector))
dom = [selector], selector = null
// 以下和上面字符串参数的重复,何意未知。
else if (fragmentRE.test(selector))
dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
//
//
else if (context !== undefined) return $(context).find(selector)
//
else dom = zepto.qsa(document, selector)
}
init是一个初始化方法,调用init时去执行zepto.Z()函数
zepto.Z = function(dom, selector) {
dom = dom || []
dom.__proto__ = $.fn;
dom.selector = selector || '';
console.log(dom)
console.log(selector)
return dom;
};
关于Z()
1 . 传入dom,如果未传则返回[]空数组
如果不传DOM节点 $(), 则返回一个空值。

2 . 如果有dom $('span'),则

3 . 同时在该数组的原型对象上创建$.fn对象
在未定义$.fn之前,dom.__proto__原型对象上的方法是Array构造函数的内置方法

而这里使用了dom.__proto__ = $.fn 重新定义了原型对象上的方法
$.fn = {
get: function () {
console.log('自定义get方法')
},
on: function () {
console.log('自定义on方法')
}
}

可以看出,通过原型对象上创建新方法后,原来的内置方法都没有了。
如果只是想追加方法,则应该在原型对象上添加属性。
dom.__proto__.get = function() {}
dom.__proto__.on = function() {}
4 . 最后返回该DOM节点对象。此时$('span')对象就可以调用方法get和on了。
Zepto源码分析之一(代码结构及初始化)的更多相关文章
- Vue.js 源码分析(一) 代码结构
关于Vue vue是一个兴起的前端js库,是一个精简的MVVM.MVVM模式是由经典的软件架构MVC衍生来的,当View(视图层)变化时,会自动更新到ViewModel(视图模型),反之亦然,View ...
- jQuery 源码分析(一) 代码结构
jQuery是一个Javascript库,它支持链式操作方式,即对发生在同一个JQuery对象上的一组动作,可以直接接连写无需要重复获取对象.这一特点使得JQuery的代码无比优雅,而且有强大的选择器 ...
- Zepto源码分析(一)核心代码分析
本文只分析核心的部分代码,并且在这部分代码有删减,但是不影响代码的正常运行. 目录 * 用闭包封装Zepto * 开始处理细节 * 正式处理数据(获取选择器选择的DOM) * 正式处理数据(添加DOM ...
- 一个普通的 Zepto 源码分析(二) - ajax 模块
一个普通的 Zepto 源码分析(二) - ajax 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块,以 ...
- Zepto源码分析(二)奇淫技巧总结
Zepto源码分析(一)核心代码分析 Zepto源码分析(二)奇淫技巧总结 目录 * 前言 * 短路操作符 * 参数重载(参数个数重载) * 参数重载(参数类型重载) * CSS操作 * 获取属性值的 ...
- MySQL源码分析以及目录结构 2
原文地址:MySQL源码分析以及目录结构作者:jacky民工 主要模块及数据流经过多年的发展,mysql的主要模块已经稳定,基本不会有大的修改.本文将对MySQL的整体架构及重要目录进行讲述. 源码结 ...
- MySQL源码分析以及目录结构
原文地址:MySQL源码分析以及目录结构作者:jacky民工 主要模块及数据流经过多年的发展,mysql的主要模块已经稳定,基本不会有大的修改.本文将对MySQL的整体架构及重要目录进行讲述. 源码结 ...
- 一个普通的 Zepto 源码分析(三) - event 模块
一个普通的 Zepto 源码分析(三) - event 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块, ...
- 一个普通的 Zepto 源码分析(一) - ie 与 form 模块
一个普通的 Zepto 源码分析(一) - ie 与 form 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核 ...
- ffplay源码分析2-数据结构
ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg提供的解码器和SDL库进行视频播放.本文基于FFmpeg工程4.1版本进行分析,其中ffplay源码清单如下: https://gith ...
随机推荐
- jquery动态添加的元素不能直接应用事件方法的时候
对于由 jQuery 动态生成的元素,如用 jQuery 给元素添加 class,或者直接添加一对 p 标签,不能直接绑定常用的事件,如 click.因为这些元素属于动态生成,除非采用 onclick ...
- PID控制算法的简单分析和仿真!
PID算法简单剖析如下: 1.首先我们来看一下PID系统的基本组成模块: 如图所示,图中相关参数的表示如下: r(t):系统实际上需要的输出值,这是一个标准值,在我们设定了之后让这个系统去逼近的一个值 ...
- B. Nirvana Codeforces Round #549 (Div. 2) (递归dfs)
---恢复内容开始--- Kurt reaches nirvana when he finds the product of all the digits of some positive integ ...
- XVIII Open Cup named after E.V. Pankratiev. Eastern Grand Prix
A. Artifacts 建立语法分析树,首先根据上下界判断是否有解,然后将所有数按下界填充,线段树判断是否存在和超过$K$的子区间. B. Brackets and Dots 最优解中一定包含一对中 ...
- css加载动画...
加载动画... <p>加载动画...</p> <p> </p> <p> </p> <style><!-- .c ...
- Tornado-基于正则的路由和动态分页
概览 这一小节涉及了三部分内容: 1.动态分页设计 2.基本的路由系统以及基于正则的路由 3.模块引擎的继承和导入 4.web项目文件夹和ReuquestHandler的分类 5.跨站脚本攻击 文件结 ...
- (51)Wangdao.com第七天_JavaScript 编写位置及输出语句
JavaScript 编写位置 编写在html内部标签的属性中 不推荐使用,因为结构和行为耦合,不便于维护 主要有 <button onclick="alert('点我干哈!');& ...
- React 面向组件化编程 - 封装了webpack - npm run build 产生的包的 /static 引用路径问题
React 面向组件化编程 面向对象 ----> 面向模块 ----> 面向组件 套路: 注意: 组件名必须大写开头: 只能有一个根标签: <input />虚拟DOM 元素必 ...
- php抓取图片进行内容提取解析,文字性pdf进行内容文字提取解析
2018年7月7日18:52:17 php是用纯算法,自己是提取图片内容不是不行,可以但是优化起来很麻烦还得设计学习库,去矫正数据的正确率 对于大多数项目来说,如果不是做ocr服务,就不必要做需求工具 ...
- String工具类2
1:比较字符串 public static void main(String[] args) { // String去创建对象有多种方式 // 方式1 直接字面值赋值 String s = " ...