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源码时记录的一些知识点,布布扣,bubuko.com

时间: 2024-10-14 10:38:19

js便签笔记(9)——解读jquery源码时记录的一些知识点的相关文章

js便签笔记(10) - 分享:json2.js源码解读笔记

1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转换成字符串.以及转换成怎样的字符串——序列化 —— JSON.stringify 接口: 以及如何将一个有效字符串转换成js对象——反序列化—— JSON.parse 接口: 2. 关于作者 json作者是 道格拉斯.克劳福德 ,是一位js大牛,写过一本<javascript语言精粹>,相信不少朋

js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2

1. 前言 昨天写了<js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1>,简单记录了几个问题.part1的重点还是在于最后那个循环创建函数的问题,也就是多个子函数公用一个闭包数据的问题.如果觉得有兴趣,可以再重新翻出来看看. 今天继续把剩下的问题写完. 2. 作用域链 学js的人,即使初级入门的也都知道“原型链”,但是“作用域链”,可能好多人没有听说过.大部分人都知道或者听说过“闭包”,但是可能有好多人不知道闭包其实和作用域链有莫大的联系.如果理解闭包不从作用域链开始理解,那么

js便签笔记(8)——js加载XML字符串或文件

1. 加载XML文件 方法1:ajax方式.代码如下: var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); xhr.open("GET", "data.xml", false); xhr.send(null); var xmlDoc = xhr.responseXML; console.log(xmlDoc

js便签笔记(13)——jsonp其实很简单【ajax跨域请求】

前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资料,原来如此... 为何一直知道jsonp,但一直迷迷糊糊的不明白呢?——网上那些介绍资料都写的太复杂了! 我是能多简单就多简单,争取让你十分钟看完! 1. 同源策略 ajax之所以需要“跨域”,罪魁祸首就是浏览器的同源策略.即,一个页面的ajax只能获取这个页面相同源或者相同域的数据. 如何叫“同源”或者“同域”呢?——协议.域名.端口号都必须相同.例如: ht

js便签笔记(14)——用nodejs搭建最简单、轻量化的http server

1. 引言 前端程序猿主要关注的是页面,你可能根本就用不到.net,java,php等后台语言. 但是你制作出来的网页总要运行.总要测试吧?——那就免不了用到http server.我先前都是用visual studio的,虽然很好用,功能很强大,但是我就开发一个html.javascript.css,干嘛用这种傻大本粗的东西.打开一次特别慢,占内存特别厉害,安装时C盘占去好几个G的空间. 后来闲来无事就换成了nodejs.不用安装任何插件,只需要手动创建三个小文件(总共才2KB),运行即可,速

js便签笔记(13)——jsonp事实上非常easy【ajax跨域请求】

前两天被问到ajax跨域怎样解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了很多资料,原来如此.. . 为何一直知道jsonp,但一直迷迷糊糊的不明确呢?--网上那些介绍资料都写的太复杂了! 我是能多简单就多简单,争取让你十分钟看完! 1. 同源策略 ajax之所以须要"跨域".罪魁祸首就是浏览器的同源策略.即,一个页面的ajax仅仅能获取这个页面同样源或者同样域的数据. 怎样叫"同源"或者"同域&quo

js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1

1. 前言 这两天看了一下TOM大叔的<深入理解js系列>中的基础部分,根据自己的实际情况,做了读书笔记,记录了部分容易绊脚的问题.写篇文章,供大家分享. 2. 关于HTMLCollection的“实时查询” var divs = document.getElementsByTagName("div"), i; for (i = 0; i < divs.length; i++) { //…… } 以上代码中,会出现性能问题.问题就在于divs是一个HTMLCollec

JQuery源码阅读记录

新建html文件,在浏览器中打开文件,在控制台输入consoole.log(window);新建html文件,引入JQuery后在浏览器中打开,在控制台同样输入consoole.log(window);会发现window下多了$(jquery)对象. 1.(function(a, b){})(window)自运行: 2.var c = a.document      , d = a.navigator      , e = a.location      , f = function(){}()

jQuery源码解析之on事件绑定

本文采用的jQuery源码为jquery-3.2.1.js jquery的on方法用来在选定的元素上绑定一个或多个事件处理函数. 当参数selector存在时,通常会用来对已经存在的元素或将来即将添加到文档中的元素做事件委托,表示当点击document中的selector元素时,将触发function回调函数. 1 <div id="div" style="font-weight:800;font-size:24px;text-align:center;color:re