近来一直利用业余时间在看jquery2.1.1源码,大约看了两千行了。平时看的时候,作了一些笔记,贴出来分享。jquery
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));
这里打印的结果就是一个真正的数组:app
另外,咱们平时所写的 $('div') ,其实也是这种伪数组,能够看一下:函数
jquery源码中有一个方法是用来判断是不是伪数组的,其中就是根据对象是否有length属性,而且对象的[length - 1]属性有没有值,来判断的。这样判断会排除掉一个特殊的类型——String,string有length属性,可是它的确不是伪数组。this
上面代码中,slice.call不只能将伪数组转化成真正的数组,还能想数组的slice同样,截取元素。以下:spa
打印的结果可想而知:prototype
2. window对象还有一个“window”属性code
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还会继续往下看,笔记也会继续整理。再有新内容,再分享。