jQuery 源码分析和使用心得 - core.js
core是jQuery的核心内容, 包含了最基础的方法, 比如我们常用的 $(selector, context), 用于遍历操作的 each, map, eq, first 识别变量类型的 isArray, isNumeric, type 等 . 这些方法为jQuery后续操作提供最基础的支持.
构造函数 jQuery( selector, context )
说到jQuery, 大家可能最熟悉的就是 $(selector, context) , 我觉得这也是jQuery受到人们欢迎的很大一部分原因, 因为这个方法非常的强大.
// Define a local copy of jQuery
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
},
这里我们很明显的看到一个关键词就是new ,这说明每一次调用$()就会new一个jQuery对象出来 , 有些人可能不注意这一点就会写出下面的代码, 或者会出现 $("#id") === $("#id")的这种判断 , 这种写法都是不可取的, 我们应该尽量的节省jQuery的获取次数, 重复利用jQuery对象.
if($(".class").hasClass()){
$(".class").removeClass();
}
静态属性和原型属性
从core.js中可以看到两类属性( q君: 函数也是属性哦! ), 一类是以jQuery.extend({})定义的静态属性, 一类是通过 jQuery.fn = jQuery.prototype = {} 进行定义的原型属性. 静态属性是jQuery函数的属性, 通过 $调用, 如$.each . 静态属性通常为与页面元素无关的工具方法. 原型属性是拓展jQuery对象的一些功能, 它持有jQuery对象自身(this) , 为处理自身对象之用 调用形式为 var $a = $("a"); $a.each() .( q君: jQuery里面有两个each ,要分清 )
具体的实现方法都比较简单, 就不再一一叙述. jQuery.extend 是一个很常用的方法, 它可以将几个对象合并成一个对象, 并且支持深拷贝和浅拷贝两种方式 , 在做一些默认配置和实现的时候会经常用到.
jQuery对象创建
通过查看 jQuery( selector, context )函数, 知道了 jQuery 调用了 new jQuery.fn.init( selector, context ). 在这句话上面有一条注释: Need init if jQuery is called . 我们在 /src/core/目录下找到init.js. 内容大致如下
init = jQuery.fn.init = function( selector, context ) {
// ...
// ...
return this;
// ...
retrun this.constructor( context ).find( selector );
// ...
return ( context || rootjQuery ).find( selector );
// ...
return typeof rootjQuery.ready !== "undefined" ?
rootjQuery.ready( selector ) :
// Execute immediately if ready is not present
selector( jQuery );
// ...
return jQuery.makeArray( selector, this ); } // Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;
在这个方法里有很多种返回.
第一种 this, 返回的是init的对象;
第二种 jquery对象.find(); -> /src/traversing/findFilter.js : find -> return this.pushStack -> return jQuery.merge( this.constructor(), elems ); -> jQuery对象
第三种 selector(jQuery); 不一定返回jQuery对象
第四种 rootjQuery.ready( selector ); -> /src/core/ready.js : ready -> return this(rootjQuery) -> jQuery对象
第五种 jQuery.makeArray( selector, this ); -> var ret = results; return ret; -> jQuery对象
通过上述观察, 发现jQuery方法只有一种情况下返回的不是jQuery对象: 传入的selector参数为对象, 并且没有加载 /src/core/ready.js 模块. 下面这段代码也会证明这种情况(代码会在附件中, 请及时更新).
<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<title>core</title>
</head> <body>
<script src="require.js" data-main="main" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
require(['../src/core/init'], function(init) {
var ret = new init(function() {
return {
name: "not jquery"
};
});
console.log(ret);
})
</script>
</body> </html>
再来看第一种情况, return this返回的是init对象, 并不是jQuery对象, 但是我们在下面看到 init.prototype = jQuery.fn; 所以通过init创建的对象也就是jQuery对象.
jQuery实现伪数组
我们在用jQuery的过程中很多情况下会把jQuery当做数组去用. 但是我们从上面创建过程来看, jQuery貌似跟数组并没有什么关系. 那么我们来分析一下他的原型看看为什么jQuery可以像数组一样使用.
在这之前我先介绍一下"鸭子类型(duck typing)" ( q君: 鸭子? 好吃吗? ), 什么是鸭子类型? “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。” 这是一个非常恰当的描述, 在动态语言中我们不需要管一个对象到底是什么类型, 只要他能执行某个方法, 那么我就可以认为他就是某个类型的对象.
Javascript就是这样的一种语言. 要实现数组不一定要继承或者使用Array对象. 只要实现了Array对象里面的方法, 就可以认为他是数组. 这里我也发现一个很有趣的事情. 用chrome浏览器进行调试的时候, 我们用console.log输出普通对象和数组的时候输出的格式不一样. 输出对象类似于 " f {length: 0} " , 输出数组类似于 " [1] ". 我们通过下面几行代码做个试验
var f = function(){this.length = 1; this[0] = "a" }
console.log(new f()); // f {0: "a", length: 1}
var f = function(){this.length = 1;this.splice = function(){};this[0] = "a" }
console.log(new f()); // ["a"]
哈, 多么神奇! chrome把他当成数组了! 如果一个对象中length为数字, splice为方法, 这个对象就会被chrome认为是数组. 大家感兴趣的话可以试一下其他的浏览器.
嗯, 我们回过头看jQuery的prototype, jQuery的prototype中包含了数组中常用的 length属性, push , sort , splice , slice等方法.
所有jQuery就像一个数组一样使用.
使用建议
1. 尽量减少重复使用 $()方法获取相同的对象
2. $() 大部分会返回jQuery对象, 但不排除在极端情况
3. jQuery可以当做数组使用, 但不完全是数组, pop, shift 等方法不适用于jQuery对象.
附件
http://yunpan.cn/Q7nKEsZ9cqFby 提取码 3a4a
jQuery 源码分析和使用心得 - core.js的更多相关文章
- jQuery 源码分析和使用心得 - 关于源码
说到jQuery, 大家可能直觉的认为jQuery的源码应该就是一个jquery.xx.js这样的一个文件. 但是看到真正的源码的时候, 整个人都思密达了.jQuery的源码做的事远比你想象的多, 为 ...
- jQuery 源码分析和使用心得 - 序
众所周知, jQuery (个人简称为jq) 在前端开发中占有着非常重要的地位, 可以说jQuery的存在大大降低了学习网页设计和交互的门槛, 他的简单的语法和顺畅的使用逻辑激发了人们强烈的学习兴趣, ...
- jQuery 源码分析和使用心得 - 文档遍历 ( traversing.js )
jQuery之所以这么好用, 首先一点就是$()方法和它强大的选择器. 其中选择器使用的是sizzle引擎, sizzle是jQuery的子项目, 提供高效的选择器查询. 有个好消息告诉大家, 就是s ...
- [转] jQuery源码分析-如何做jQuery源码分析
jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)
在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...
- [转]jQuery源码分析系列
文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...
- jquery源码分析之一前言篇
1.问:jquery源码分析的版本是什么? 答:v3.2.1 2.问:为什么要分析jquery源码? 答:javascript是一切js框架的基础,jquery.es6.vue.angular.rea ...
- jQuery源码分析-each函数
本文部分截取自且行且思 jQuery.each方法用于遍历一个数组或对象,并对当前遍历的元素进行处理,在jQuery使用的频率非常大,下面就这个函数做了详细讲解: 复制代码代码 /*! * jQuer ...
随机推荐
- 什么是 CSS 预处理器?
什么是 CSS 预处理器? 就CSS本身而言,对于大多数Web前端从业人员来说就不是问题.学过CSS的人都知道,它不是一种编程语言.你可以用它开发网页样式,但是没法用它编程.换句话说,CSS基本上是 ...
- 【转】这些隐藏在苹果iPhone当中的内置代码你是否知道?
原文地址:http://www.ithome.com/html/iphone/200569.htm 每一部手机都有一些内置的隐藏代码,我们称之为“指令”,这些代码加在一起就叫做“指令集”.当然这些代码 ...
- UIButton, KVC, KVO
按钮 自定义按钮:调整内部子控件的frame 方式1:实现titleRectForContentRect:和imageRectForContentRect:方法,分别返回titleLabel和imag ...
- web.config详解
在开发中经常会遇到这样的情况,在部署程序时为了保密起见并不将源代码随项目一同发布,而我们开发时的环境与部署环境可能不一致(比如数据库不一样),如果在代码中保存这些配置这些信息部署时需要到用户那里更改代 ...
- PHP json_encode()函数使用
<?php $tmp = array(); echo json_encode($tmp); //打印 [] echo "\n"; echo json_encode($tmp, ...
- jquery与ajax的应用
1.编写第一个Ajax的例子,先来看一下传统的JavaScript实现的ajax例子. 首先在前台页面中书写HTML代码. <input type="button" valu ...
- RenderPartial: No overload for method 'Write' takes 0 arguments
如下方法调用RenderPartial: 报“No overload for method 'Write' takes 0 arguments”的错误: @if (@Model != null &am ...
- Linux03--文件打包与解压
参考了<鸟哥的Linux私房菜> 1.压缩命令 gzip(压缩)与zcat(解压并读出来) gzip 可以说是应用度最广的压缩命令了!目前 gzip 可以解开 compress, zip ...
- VS2012编译错误信息,错误列表却没显示
今天在写代码的时候,发现VS有编译错误,在错误列表里面却没有显示错误信息,百思不得其解. 后来终于发现,错误列表弄了个筛选,所以就看不到错误信息了,晕死.有遇到该问题的,可以参考下.
- android4.0 HttpClient 以后不能在主线程发起网络请求
android4.0以后不能在主线程发起网络请求,该异步网络请求. new Thread(new Runnable() { @Override public void run() { // TODO ...