js便签笔记(9)——解读jquery源码时记录的一些知识点
近来一直利用业余时间在看jquery2.1.1源码,大约看了两千行了。平时看的时候,做了一些笔记,贴出来分享。
1. Array.prototype.slice.call 可以将伪数组转化为真正的数组
其实,这里所谓的“伪数组”就是有length属性,并且有“0”、“1”、“2”等这些属性的对象,如下代码:
var obj = {
0: "A",
1: "B",
2: "C",
length: 3
};
var slice = [].slice;
console.log(slice.call(obj));
这里打印的结果就是一个真正的数组:

另外,我们平时所写的 $('div') ,其实也是这种伪数组,可以看一下:

jquery源码中有一个方法是用来判断是否是伪数组的,其中就是根据对象是否有length属性,并且对象的[length - 1]属性有没有值,来判断的。这样判断会排除掉一个特殊的类型——String,string有length属性,但是它的确不是伪数组。
上面代码中,slice.call不仅能将伪数组转化成真正的数组,还能想数组的slice一样,截取元素。如下:

打印的结果可想而知:

2. window对象还有一个“window”属性
jquery源码中,判断一个对象是否是window的时候,用以下方法来判断:
return obj.window === window;
用浏览器监测以下window对象的细节,会发现,window对象下确实还有一个window对象,而且是一个无限循环的结构。
3. 快捷方法
第一:

第二:
将一个对象强制转换为与之对应的bool类型,可用: !!obj
相反,如果转换成一直相反的bool类型,可用: !obj
4. === 与 ==
=== 是严格相等,不会进行类型转换,而 == 是不严格相等,会进行类型转换。有些js的书中,建议开发人员永远不要用 == 或者 != 。
但是jquery源码中,有用到“==”或者“!=”的情况 —— 判断 undefined 和 null 的时候。

5. 重写了 toString()
有些对象类型重写了 toString 方法,因此要获取这个对象的名称,就不能简单的用 .toString() ,而是用 Object.prototype.toString.call
var a = [1, 2];
console.log(a.toString()); // 1,2
console.log(Object.prototype.toString.call(a)); // [Object Array]
6. Object( 'str' ) —— String强制类型转换为Object
将一个字符串强制类型转换成object之后,将会返回一个标准的伪数组对象。
Object( 'abc' ) --> String {0: "a", 1: "b", 2: "c", length: 3}
7. jQuery的each函数,最大的优点
each函数相比于for循环,最大的改进在于封闭了独立的函数作用域。
先看一段for循环的代码:
console.log("current this", this);
var $divs = $("div"),
index = 0,
length = $divs.length;
for (; index < length; index++) {
console.log(index, this);
var j = 200;
}
console.log(j);
打印的结果如下:

打印结果可以看出:for循环里面的语句块,和外面的作用域相同;最可怕的是 for 循环里面定义的变量,在外面可以识别。 别伤心,这就是js的一个“特点”。
为了解决这个问题,我们再看看each函数的代码:
console.log("current this", this);
var $divs = $("div");
$divs.each(function (index, elem) {
console.log(index, this);
var x = 100;
});
console.log(x);
打印结果如下:

很容易看出,each函数中的作用域,和外部作用域不同,而且each函数中定义的变量完全是局部变量,外面不可获取。这正式我们想要的!
另外,大家还肯能会发现,each比较类似与 for ... in 。 for...in 是迭代器模式,比 for(i=0;i<length;i++)要方便很多。但是除了上面提到了作用域之外,each和for...in就完全一样了吗? 当然不是!

以上两段代码,结果却大相径庭。为何? 因为 for...in 会遍历一个对象的隐式原型元素,而 each 则像for(i=0;i<length;i++)一样中规中矩。
8. call和apply的参数传递不同
他俩的传参方式不同可能大家都知道,说一个具体的例子吧,jquery中用到的。
var arr = [5, 6, [1, 2], [3, 4]];
console.log(Array.prototype.concat.call([], arr)); // [5, 6, [1, 2], [3, 4]]
console.log(Array.prototype.concat.apply([], arr)); // [5, 6, 1, 2, 3, 4]
以上代码,输出的结果完全不一样。看明白这一点,才能说明你真正理解了两者传参的不同。
---------------------------------------------------------------
以上是本次全部内容。jquery还会继续往下看,笔记也会继续整理。再有新内容,再分享。
js便签笔记(9)——解读jquery源码时记录的一些知识点的更多相关文章
- 分析jQuery源码时记录的一点感悟
分析jQuery源码时记录的一点感悟 1. 链式写法 这是jQuery语法上的最大特色,也许该改改POJO里的set方法,和其他的非get方法什么的,可以把多行代码合并,减去每次 ...
- js便签笔记(2)——DOM元素的特性(Attribute)和属性(Property)
1.介绍: 上篇js便签笔记http://www.cnblogs.com/wangfupeng1988/p/3626300.html最后提到了dom元素的Attribute和Property,本文简单 ...
- js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2
1. 前言 昨天写了<js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1>,简单记录了几个问题.part1的重点还是在于最后那个循环创建函数的问题,也就是多个子函数公用一个闭 ...
- js便签笔记(5)——Dean Edwards大牛的跨浏览器AddEvent()设计(不知道是不是jQuery事件系统的原型)
1. 前言: 在看Aaron的jquery源码解读时候,看到事件系统那块,作者提到了Dean Edwards的添加事件的设计,于是就点进去看了看.首先让我吃惊的是,代码非常少,寥寥几十行,非常简单.于 ...
- js便签笔记(7)——style、currentStyle、getComputedStyle区别介绍【转载】
转者语: 今天看jQuery源码CSS部分,里面用到了currentStyle和getComputedStyle来获取外部样式. 因为elem.style.width只能获取elem的style属性里 ...
- js便签笔记(10) - 分享:json2.js源码解读笔记
1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...
- js便签笔记(10) - 分享:json.js源码解读笔记
1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...
- js便签笔记(6)——jQuery中的ready()事件为何需要那么多代码?
前言: ready()事件的应用,是大家再熟悉不过的了,学jQuery的第一步,最最常见的代码: jQuery(document).ready(function () { }); jQuery(fun ...
- js便签笔记(13)——jsonp其实很简单【ajax跨域请求】
前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资料,原来如此... 为何一直知道jsonp,但一直迷迷糊糊的不明白 ...
随机推荐
- 树形控件(CTreeCtrl和CTreeView)
如何插入数据项目? 如何添加鼠标右击事件? 插入数据项 通过InsertItem()方法,有四种重载样式: HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsert ...
- winSockets编程(四)阻塞模式(服务端)
在阻塞模式下,在I/O操作完成前,执行的操作函数将一直等候而不会立即返回,该函数所在的线程会阻塞在这里.相反,在非阻塞模式下,套接字函数立即返回,而不管I/O是否完成. 重点知识和思想: ////// ...
- Scala_数据结构
数据结构 容器(Collection) Scala提供了一套丰富的容器(collection)库,包括列表 (List).数组(Array).集合(Set).映射(Map)等 根据容器中元素的组织方式 ...
- telerik:RadGrid 分组自动展开
在 MasterTableView 加上 GroupsDefaultExpanded = " true " 即可 自动展开分组下面的子项
- Ocelot入门实践
博主是第一次写技术文档,一是对这两年工作以来的一些技术和经验进行整理,二也是希望能和大家多多分享交流,如有写的不对的地方望大家多多指正.进入正题 Ocelot 概念就不说了,大家自行百度,今天做一个O ...
- 关于Entity Framework的概念及搭建
什么是EF? ADO.NET Entity Framework 是一个对象-关系的映射架构. 它支持直接定义完全独立于数据库结构的实体类,并把它们映射到数据库的表和关系上. 三种编程模型: 数据库优先 ...
- Could not find installable ISAM
程序中去读EXCEL文档,以前一直参考<Asp.net读取Excel文件 2>http://www.cnblogs.com/insus/archive/2011/05/05/2037808 ...
- XML hexadecimal value 0x__, is an invalid character
XML操作时异常:(十六进制值 0x__) 是无效的字符. 方法一: 设置 CheckCharacters=false. XmlReaderSettings xmlReaderSettings = n ...
- 输入URL地址到最终页面渲染完成,发生了什么事
1. 域名DNS解析 - 浏览器DNS缓存 - 系统DNS缓存 - 路由器DNS缓存 - 网络运营商DNS缓存 - 递归搜索...... 2. TCP连接: TCP三次握手 - 第一次握手,由浏览器发 ...
- Python黑客——快速编写信息收集器
i春秋作家:大木瓜 环境:Python 3模块:LxmlRequestBeautifulsoup开始:首先看一下目标站: http://gaokao.chsi.com.cn/gkxx/zszcgd/d ...