将类数组对象转化为数组对象

javascript中有许多类数组对象,比如HTMLCollection,NodeList,arguments。她们的特点是和数组一样有length属性,并且有0,1,2这样的位置属性。在代码编写中我们经常需要将他们转化为数组对象。

//mini类数组对象
var arrayLike = {
0: "a",
1: "b",
2: "c",
length: 3
}
console.log(Array.prototype.slice.call(arrayLike))

我们来详细分析一下Array.prototype.slice.call(arrayLike)。数组的中有slice方法,存放在数组的原型中也就是Array.prototype.slice,它操作的返回值是一个数组;call具有修改上下文的作用,本例就是将slice的上下文改为arrayLike。所以这句话就实现了将类数组对象转化为数组对象的功能。

.get()实现

var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context );
};
jQuery.fn = jQuery.prototype = {
init: function(selector){
this.selector = selector;
//从IE8之后提供了querySelectorAll,我们先利用它mini化选择器
//返回的是伪数组对象NodeList
var result = document.querySelectorAll(selector);
//将NodeList转化为jQuery对象。
for(var i = 0;i < result.length;i++){
this[i] = result[i]
}
//模拟jQuery对象的length属性
this.length = result.length;
}
}
jQuery.fn.init.prototype = jQuery.fn
//不利用extend ,直接向原型里添加属性方法get
jQuery.fn.get = function(index) {
return index != null ? (index < 0 ? this[this.length + index]:this[index]):Array.prototype.slice.call(this);
}
//测试
console.log(jQuery("div").get(0))

.get的作用是转化为DOM节点,或者是DOM节点数组。注意一些特别的情况。

.eq()实现

var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context );
};
jQuery.fn = jQuery.prototype = {
selector: "",
init: function(selector){
//仍然是mini的选择器。
var result = document.querySelectorAll(selector);
for(var i = 0;i < result.length;i++){
this[i] = result[i]
}
this.length = result.length;
},
pushStack: function( elems ) {
//将空jQuery对象和elems合并
var ret = jQuery.merge( this.constructor(), elems );
//设置前一个对象,作回来的索引。
ret.prevObject = this; // 新形成jQuery的对象
return ret;
},
eq : function( i ) {
//将负数位置转化为正数位置
var j = + i + ( i < 0 ? this.length:0);
//在范围内返回指定对象包成的数组,否则返回空数组
return this.pushStack((j >= 0&& j<this.length)?[this[j]]:[])
},
//将原型的构造函数设置为jQuery,可以用jQuery.constructor创造新的空对象;相关语句this.constructor;jQuery.prototype;
constructor : jQuery
}
jQuery.fn.init.prototype = jQuery.fn
//将两个类数组对象或数组对象合并,并设置,length
jQuery.merge = function( first, second ) {
var len = +second.length,
j = 0,
i = first.length;
for ( ; j < len; j++ ) {
first[ i++ ] = second[ j ];
} first.length = i; return first;
};
//测试
console.log(jQuery("div").eq(0))

先讲两个相关函数jQuery.fn.pushStatic和jQuery.merge。

写在jQuery.fn里的函数实际写在原型里,用到这个原型的构造函数都会继承;而写在jQuery里的实际是在一个独立的jQuery对象,只能通过jQuery.[函数名]的形式引用。

merge实际的功能是合并两个数组或者类数组对象,放到第一个对象中,并设置他们合并后的长度。pushStatic调用了merge,第一个参数为jQuery空对象(this.constructor()),将第二个数组或者类数组合并到jQuery空对象中,形成新的jQuery对象,并返回。

eq的功能就是get的功能多一个转化成jQuery对象,调用pushStatic,并返回其返回值一个新的jQuery对象。

first和last和end

  first: function() {
return this.eq( 0 );
}, last: function() {
return this.eq( -1 );
}, end: function() {
return this.prevObject || this.constructor(null);
},

jQuery源码笔记——三的更多相关文章

  1. jQuery源码笔记(一):jQuery的整体结构

    jQuery 是一个非常优秀的 JS 库,与 Prototype,YUI,Mootools 等众多的 Js 类库相比,它剑走偏锋,从 web 开发的实用角度出发,抛除了其它 Lib 中一些中看但不实用 ...

  2. Tomcat8源码笔记(三)Catalina加载过程

    之前介绍过 Catalina加载过程是Bootstrap的load调用的  Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...

  3. jQuery源码解读三选择器

    直接上jQuery源码截取代码 // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ i ...

  4. jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...

  5. jQuery 源码解析(三) pushStack方法 详解

    该函数用于创建一个新的jQuery对象,然后将一个DOM元素集合加入到jQuery栈中,最后返回该jQuery对象,有三个参数,如下: elems Array类型 将要压入 jQuery 栈的数组元素 ...

  6. jQuery 源码解析(三十) 动画模块 $.animate()详解

    jQuery的动画模块提供了包括隐藏显示动画.渐显渐隐动画.滑入划出动画,同时还支持构造复杂自定义动画,动画模块用到了之前讲解过的很多其它很多模块,例如队列.事件等等, $.animate()的用法如 ...

  7. jQuery源码笔记——二

    jQuery选择这样返回对象 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, con ...

  8. jQuery源码笔记——回调对象

    回调对象是一个多用途的回调列表对象,提供了强大的的方式来管理回调函数列表. 最简单的缓存对象 function Callbacks(){ var list = [], self = { add: fu ...

  9. jQuery源码笔记——延迟对象

    提供一种方法来执行一个或多个对象的回调函数, Deferred对象通常表示异步事件. 它是回调对象的拓展运用,在jQuery当中非常依赖回调对象. 一个简单的,只解决成功状态下的缓存实例 functi ...

随机推荐

  1. hdu 1150 Machine Schedule hdu 1151 Air Raid 匈牙利模版

    //两道大水……哦不 两道结论题 结论:二部图的最小覆盖数=二部图的最大匹配数 有向图的最小覆盖数=节点数-二部图的最大匹配数 //hdu 1150 #include<cstdio> #i ...

  2. 杭电oj 1009 FatMouse' Trade

    Tips:本题采用贪心算法,类似于背包问题,关键在于读入数据之后,将数据按 J[i]/F[i] 从大到小排列即可. /**本程序主要采用贪心算法思想,类似于背包问题*/ #include<std ...

  3. .net控件dropdownlist动态绑定数据 ----转

    DropDownList控件的使用(数据绑定)(.net学习笔记二) 一.在页面初始化时候将集合绑定到DropDownListpublic void Page_Load(Object src.Even ...

  4. JavaScript中forEach的用法相关

    首先说下JavaScript的forEach的标准格式. 为数组中的每个元素执行指定操作. array1.forEach(callbackfn[, thisArg]) 参数 定义 array1 必需. ...

  5. iOS集成微信支付

    微信支付的开发 前言:之前听说过微信支付有很多坑,其实没有想象的那么坑,整体感觉很容易上手,按照它的流程来不会有错!PS:官方的流程看的TMD烦,好啦,废话有点多,进入开发.(ps:每个微信的版本一直 ...

  6. C# for 循环 迭代法 穷举法

    for()循环. 四要素: 初始条件,循环条件,状态改变,循环体. 执行过程: 初始条件--循环条件--循环体--状态改变--循环条件.... 注意:for的小括号里面分号隔开,for的小括号后不要加 ...

  7. 用GoEasy推送实现Java实时推送

    前段时间客户有个需求他希望他在后台管理页面发布一个消息,所有用这个系统的用户无论在哪个页面都能及时收到他发布的信息,以前对于类似需求在少量 页面接收的前提下,我一般采用ajax定时去服务器pull信息 ...

  8. Char型和string型字符串比较整理

    1.赋值 char赋值: char ch1[] = "give me"; char ch2[] = "a cup"; strcpy(ch1,ch2); cout ...

  9. Android 相对布局常用属性

    Android 布局属性详解 RelativeLayout用到的一些重要的属性: 第一类:属性值为true或false     android:layout_centerHrizontal  水平居中 ...

  10. div模拟textarea以实现高度自适应实例页面

    作为多行文本域功能来讲,textarea满足了我们大部分的需求.然而,textarea有一个不足就是不能像普通div标签一样高度可以跟随内容自适应.textarea总是很自信地显摆它的滚动条,高度固执 ...