zepto源码分析
2017-01-20 17:51
344 查看
改变数组对象的原型
首先我们看一下如下代码,如何给一个数组对象添加其他方法var arr = [1,2,3]; arr.__proto__ = { addClass: function () { console.log('this is addClass'); }, concat: Array.prototype.concat, push: Array.prototype.push }; arr.push(4); // [1, 2, 3, 4] arr.addClass(); // 'addClass'
我们修改了数组arr的隐式原型
__proto__,使它拥有了更多方法,更多原型继承可以参考另一篇博文原型继承与应用。zepto的原理也是这样:通过$()选择器返回的类数组对象,将对象的隐式原型修改,使zepto对象具有多种方法可以被我们使用
入口
zepto主要结构如下所示,先使用iife(立即执行函数)返回一个值,然后把这个返回值放在window的Zepto属性中,也就是说Zepto成为了一个全局变量。window.$ === false && expression,这是一个简洁写法,意为第一个表达式为false时返回第二个表达式,也就是执行expression。当
$没被定义时将
$函数赋值给Zepto。所以我们引用
$()的时候,实际上是引用Zepto。
var Zepto = (function(){ }() window.Zepto = Zepto; window.$ === undefined && (window.$ = Zepto)
显而易见,IIFE的返回值是一个对象,因为我们经过
$()选择元素之后,可以使用一系列方法,如addClass ,find等等。那么这个对象是什么,请看以下代码
var Zepto = (function(){ var $; $ = function(selector, context){ return zepto.init(selector, context) } return $; }()
当我们使用
$('#aa')的时候,其实执行的是
Zepto('#aa'),也就是IIFE的返回值
$(selector, context),也就是
zepto.init(selector, context)
init函数
zepto.init = function(selector, context){ var dom; // 分情况对dom赋值: // 1. selector 为空 // 2. selector 是字符串,其中又分好几种情况 // 3. selector 是函数 // 4. 其他情况,例如 selector 是数组、对象等 return zepto.Z(dom, selector) }
主逻辑转移到了zepto.Z函数中
zepto.Z函数
上个版本的Z函数是这样实现的:zepto.Z = function(dom, selector){ //如果dom数组没有取到就初始化为数组 dom = dom || []; //源码核心,dom数组的隐式原型被改变了,fn就是这个原型 dom.__proto__ = $.fn //js中 a||b 是一种赋值方式,当a不为真的时候返回b dom.selector = selector || '' return dom; }
最新版本的Z函数如下:
function Z(dom, selector){ var i, len = dom ? dom.length : 0 //进行一次浅拷贝 for(i = 0; i< len; i++) this[i] = dom[i] this.length = len this.selector = selector || '' } zepto.Z = function(dom, selector){ return new Z(); } zepto.Z.prototype = Z.prototype = $.fn
这种方法直接改变了构造函数Z的原型,导致new出来的对象的
__proto__指向$.fn,和上面的方法效果相同,唯一不同的是,最新的Z函数返回的是像
{ 0: dom[0], 1: dom[1], 2: dom[2], length: 3, selector: '' }
前者的对象称为类数组对象,而原来是数组
[dom[0], dom[1], dom[2]]
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- Python动态类型的学习---引用的理解
- 从源码安装Mysql/Percona 5.5
- 只需四个步骤几行代码,即可快速实现直播弹幕功能
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- JavaScript 基础、进阶以及 Ubuntu 系统中的 JavaScript 开发调试工具
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 设计模式---状态模式在web前端中的应用
- SUI踩坑记录
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)