您的位置:首页 > Web前端 > JavaScript

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]]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  源码 对象 javascript