//添加实例属性和方法
jQuery.fn = jQuery.prototype = {
// 版本,使用方式:$().jquery弹出当前引入的jquery的版本
jquery: core_version,
// 修正指向问题(后有详解)
constructor: jQuery, // 初始化和参数管理
init: function( selector, context, rootjQuery ) {
var match, elem; // 写错之后的处理,如果写成: $(""), $(null), $(undefined), $(false),直接返回
if ( !selector ) {
return this;
}
// 对字符串进行处理
if ( typeof selector === "string" ) {
// 如果是这种$('<li>')或$('<li>1</li><li>2</li>')
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// match = [ null, '<li>', null ];或者 match = [ null, '<li>1</li><li>2</li>', null ];
match = [ null, selector, null ];
//如果是$('#div1') $('.box') $('div') $('#div1 div.box')
} else {
//$('.box') $('div') $('#div1 div.box') match = null;
//$('#div1') match = ['#div1',null,'div1'];
//$('<li>hello') match = ['<li>hello','<li>',null];
match = rquickExpr.exec( selector ); //exec()后面详解
} // $('<li>') $('#div1') //$('#div1')的上下文为空,即context为false
if ( match && (match[1] || !context) ) {
if ( match[1] ) {
// 如果是$('<li>',document)填写了第二个对象,并且第二个对象是原生,则直接返回该对象;$('<li>',$(document))如果返回的第二个对象是jQuery,则将它转换成原生的对象
context = context instanceof jQuery ? context[0] : context;
// 1、jQuery.parseHTML()函数用于将HTML字符串解析为对应的DOM节点数组;使用一个HTML字符串创建一个数组的DOM节点
jQuery.merge( this, jQuery.parseHTML(
match[1], //需要解析并转成DOM节点数组的HTML字符串
//指定在哪个Document中创建元素,默认为当前文档的document,可能是iframe
context && context.nodeType ? context.ownerDocument || context : document,
//true,Boolean类型指定传入的HTML字符串中是否包含脚本,默认为false
true
) ); // 1、rsingleTag.test( match[1] )匹配单标签,只能匹配<li>或<li></li>,其他都不行
// 2、jQuery.isPlainObject( context )函数用于判断指定参数是否是一个纯粹的对象。{ } 或new Object()或{ name: "CodePlayer"}
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
for ( match in context ) {
// jQuery.isFunction用于判断参数是否是一个函数
if ( jQuery.isFunction( this[ match ] ) ) {
//如果是函数就直接调用该函数,示例:$('<li></li>',{title : 'hi',html : 'abcd',css : {background:'red'}}).appendTo( 'ul' );其中html : 'abcd'就相当于this.html('abcd')
this[ match ]( context[ match ] );
} else {
//如果不是函数就直接添加属性
this.attr( match, context[ match ] );
}
}
} return this; // $('#div1')选择元素
} else {
elem = document.getElementById( match[2] ); if ( elem && elem.parentNode ) {
// Inject the element directly into the jQuery object
this.length = 1;
this[0] = elem;
} this.context = document;
this.selector = selector;
return this;
} } else if ( !context || context.jquery ) {
return ( context || rootjQuery ).find( selector ); } else {
return this.constructor( context ).find( selector );
} //对DOM元素进行处理,$(this),$(document)。
//nodeType属性返回以数字值返回指定节点的节点类型。如果是元素节点,返回1;如果是属性节点,返回2
} else if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this; // 对函数进行处理
} else if ( jQuery.isFunction( selector ) ) {
// 如果是函数$(function(){}),返回$(document).ready(function(){});
return rootjQuery.ready( selector );
}
// 对空对象或空数组进行处理
if ( selector.selector !== undefined ) {
this.selector = selector.selector;
this.context = selector.context;
}
// jQuery.makeArray()函数用于将一个类数组对象转换为真正的数组对象(详解)
return jQuery.makeArray( selector, this );
},
// selector 存储选择字符串;
selector: "",
// length this对象的长度
length: 0,
// toArray 专数组
toArray: function() {
return core_slice.call( this );
}, // get 转原生合集
get: function( num ) {
return num == null ? // Return a 'clean' array
this.toArray() : // Return just the object
( num < 0 ? this[ this.length + num ] : this[ num ] );
}, // pushStack JQ对象的入栈(先进后出)
pushStack: function( elems ) { // Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context; // Return the newly-formed element set
return ret;
}, // each 遍历集合
each: function( callback, args ) {
return jQuery.each( this, callback, args );
},
// DOM加载接口
ready: function( fn ) {
jQuery.ready.promise().done( fn ); return this;
},
// 集合的截取
slice: function() {
return this.pushStack( core_slice.apply( this, arguments ) );
},
// 集合的第一项
first: function() {
return this.eq( 0 );
},
// 集合的最后一项
last: function() {
return this.eq( -1 );
},
// 集合的指定项
eq: function( i ) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 );
return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
},
// 返回新集合
map: function( callback ) {
return this.pushStack( jQuery.map(this, function( elem, i ) {
return callback.call( elem, i, elem );
}));
},
// 返回集合前一个状态
end: function() {
return this.prevObject || this.constructor(null);
}, // push、sort、splice内部使用
push: core_push,
sort: [].sort,
splice: [].splice
};

部分详解

1、constructor: jQuery

示例:

// js源码在构造函数创建完就自动生成了
function Aaa(){};
Aaa.prototype.constructor = Aaa;
var a = new Aaa();
alert(a.constructor); // function Aaa(){}; Aaa.prototype.constructor = Array;
alert(a.constructor); // function Array() { [native code] } Aaa.prototype = {
constructor : Aaa,
name : 'hello',
age : 30
};
var a1 = new Aaa();
alert(a1.constructor); // function Aaa(){};

这个constructor属性非常容易被不小心修改掉,所以jquery需要修正指向

2、match = rquickExpr.exec( selector )

示例:

var  rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;
var selector = "#div1";
var match = rquickExpr.exec( selector );
console.log(match); //match = ['#div1',null,'div1'];

exec() 方法就是用来检索字符串中正则表达式的匹配,如果匹配到了那么就返回一个存放有结果的数组,如果没有匹配到就返回一个null;

match是数组,第0个元素是与正则表达式相匹配的文本,第1个元素是与正则表达式的第1个子表达式相匹配的文本(如果有的话),第2个元素是第2个子表达式相匹配的文本(如果有的话),第3个元素是第3个子表达式相匹配的文本(如果有的话),这里就是元素的ID,不包含#。

3、jQuery.makeArray()

var aDiv = document.getElementsByTagName('div');

aDiv并不是一个真正的数组,可以用$.makeArray(aDiv)转成一个数组 ;$.makeArray(aDiv,{length:0})将它转成一个对象

$([]) $({})

jQuery源码学习笔记二的更多相关文章

  1. jquery源码学习笔记二:jQuery工厂

    笔记一里记录,jQuery的总体结构如下: (function( global, factory ) { //调用factory(工厂)生成jQuery实例 factory( global ); }( ...

  2. jquery源码学习笔记三:jQuery工厂剖析

    jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...

  3. 菜鸟的jQuery源码学习笔记(前言)

    前言 相信任何一名前端开发人员或者是前端爱好者都对jQuery不陌生.jQuery简单易用,功能强大,特别是拥有良好的浏览器兼容性,大大降低了前端开发的难度,使得前端开发变得“平易近人起来”.自从本人 ...

  4. jQuery源码学习笔记一

    学习jQuery源码,我主要是通过妙味视频上学习的.这里将所有的源码分析,还有一些自己弄懂过程中的方法及示例整理出来,供大家参考. 我用的jquery v2.0.3版本. var rootjQuery ...

  5. jquery源码学习笔记(一)jQuery的无new构建

    本人是一名.net程序员..... 你一个.net coder 看什么jQuery 源码啊? 原因吗,很简单.技多不压身吗(麻蛋,前端工作好高...羡慕). 我一直都很喜欢JavaScript,废话不 ...

  6. jquery源码学习笔记一:总体结构

    练武不练功,到老一场空.计算机也一样. 计算机的功,就是原理.如果程序员只会使用各种函数,各种框架,而不知其原理,顶多熟练工人而已.知其然,更要知其所以然. jquery我们用得很爽,但它究竟咋实现的 ...

  7. jQuery 源码学习笔记

    //检测 window 中新增的对象 //first var oldMap = {}; for(var i in window) { oldMap[i] = 1; } //second for(var ...

  8. 菜鸟的jQuery源码学习笔记(二)

    jQuery对象是使用构造函数和原型模式相结合的方式创建的.现在来看看jQuery的原型对象jQuery.prototype: jQuery.fn = jQuery.prototype = { //成 ...

  9. jquery 源码学习(二)

    在网上找到一篇广为流传的文章<常用正则表达式>,逐一分析,不足地方进行补充和纠正   作者:nuysoft/JS攻城师/高云 QQ:47214707 EMail:nuysoft@gmail ...

随机推荐

  1. 在Ubuntu中增加root用户登录

    一:增加root用户登录 1.打开终端,输入:sudo gedit /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf 2.在弹出的编辑框里输入:gree ...

  2. vue项目在IE下报 [vuex] vuex requires a Promise polyfill in this browser问题

    如下图所示,项目在IE11下打开报错: 因为使用了 ES6 中用来传递异步消息的的Promise,而IE浏览器都不支持. 解决方法: 第一步: 安装 babel-polyfill . babel-po ...

  3. Markdown 常用操作

    1->水平线 注意,使用时发现,水平线的语句上一行必须为空行,不然水平线不生效 *** 或者 --- ------->效果: 2->标题 # 大 ## 大 ### 大 #### 大 ...

  4. POJ 1095

    #include <iostream> #define MAXN 20 using namespace std; __int64 cat[MAXN]; int sum; void give ...

  5. android Service 学习总结

    学习android开发已经四五个月,由于项目中职责的原因一直没有接触过Service的实际项目,今天重新学一遍Service用法. 问题: 作为四大组件,为什么需要Service? 它与Thread又 ...

  6. Linux的管道命令

    Linux的管道命令 管道命令(Pipe) 管道命令用"|"来表示,管道命令需要接收前一个命令的输出来进行操作,但不能处理前一个命令的错误. //选取界面:cut,grep cut ...

  7. winrar 命令行 解压文件

    1,最简单的压缩命令:winrar a asdf.txt.rar asdf.txt a的意思是进行压缩动作,后面第一个参数是被压缩后的文件名,后缀当然是rar了,最后面 的参数就是要被压缩的文件名 2 ...

  8. android瓦片地图技术研究

    最近根据公司项目需求,需要制作场馆的室内图并且实现根据rfid信号的自动定位功能,研究了好久找到了一个目前为止还算好用的瓦片地图工具——TileView. github连接:https://githu ...

  9. SPSS学习系列之SPSS Modeler (简称SPSS)是什么?

    不多说,直接上干货! 推荐博客 SPSS学习系列之SPSS Statistics(简称SPSS)是什么? 官方简介: SPSS Modeler 是全球领先的数据挖掘.预测分析平台软件,拥有简单的图形界 ...

  10. GBDT多分类示例

    相当于每次都是用2分类,然后不停的训练,最后把所有的弱分类器来进行汇总 样本编号 花萼长度(cm) 花萼宽度(cm) 花瓣长度(cm) 花瓣宽度 花的种类 1 5.1 3.5 1.4 0.2 山鸢尾 ...