【jQuery-1.7.2源码分析】extend

jQ的扩展分两种

 

1. 把相对紧凑的方法统一在一处,因此,在内部写法上看起来是一个个的模块,这样便于维护。其中分为两类:

1) 基于jQuery这个对象,也就是静态属性/方法的作用,这部分的扩展更为通用,比如 attr: function( elem, name, value, pass ),脱离jQ对象也可以使用

2) 基于 prototype 的,内部大多只是借用了静态属性/方法

 

2. 当作工具方法

如需要给obj = {a:1, b:2}对象加几个属性,就直接obj = jQuery.extend(obj, {})

 

这部分没啥好说的,就一个方法,而且不长,我不打算贴原版代码,因为我觉得凡是jQ的写法都要批判着看,它的确功能强大,但不代表连带它的代码风格都要推广。


下面给出我的版本,如果需要原版,请自行下载。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 关于这个方法的形参,我个人认为使这样的:
// 如果是 extend(<1>),表示给jQ对象扩展<1>的功能
// 如果是 extend(<0>, <1>), 则表示给<0>扩展<1>的功能
//
// 需要提醒一下,<1>不仅可以是一个{},还可以是多个{},即扩展多种功能
// 除此之外,第一个参数还可以是boolean,表示是否深拷贝,这样的话
// 剩下的参数都要往后移一位
jQuery.extend = jQuery.fn.extend = function () {
     // 默认的处理是理想情况,即extend(<0>, <1>)
     var  target = arguments[0], // target 表示给谁扩展
         deep = false ,          // 是否需要深拷贝, 默认不需要
         i = 1;                 // i表示扩展的部分从第几个参数开始
 
     if  ( typeof  target === 'boolean' ) {
         // 指定是否需要深拷贝
         deep = target;
         // 移位
         target = arguments[1];
         i = 2;
     }
 
     // 到这里因为已经确定了target
     // 所以需要判断一下target是否合法
     if  ( typeof  target !== 'object'  && !jQuery.isFunction(target)) {
         target = {};
     }
 
     var  length = arguments.length;
     // 不存在<1>的情况,也就是扩展目标是jQ对象
     if  (length === i) {
         // 再次移位
         target = this ;
         i--;
     }
 
     var  options, name, src, copy, copyIsArray, clone;
     for  (; i < length; i++) {
         if  ((options = arguments[i]) != null ) {
             // options也可以是数组哦
             for  (name in  options) {
                 src = target[name];
                 copy = options[name];
 
                 // 如果相等会出现死循环
                 if  (target === copy) {
                     continue ;
                 }
 
                 // 深拷贝就是去递归
                 if  (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
                     // 这里需要保证是同类型的拷贝,即 object > object, array > array
                     if  (copyIsArray) {
                         // 重置,不然的话,如果jQuery.isPlainObject(copy)为true会出问题
                         copyIsArray = false ;
                         clone = src && jQuery.isArray(src) ? src : [];
                     } else  {
                         clone = src && jQuery.isPlainObject(src) ? src : {};
                     }
                     // 这次扩展的目标就不是jQ对象了,而是clone
                     target[name] = jQuery.extend(deep, clone, copy);
                 
                 // 我觉得copy不可能出现 undefined 吧
                 // 除非是 {key: undefined} 这么写代码真是够蛋疼的
                 } else  if  (copy !== 'undefined' ) {
                     target[name] = copy;
                 }
             }
         }
     }
     return  target;
};

  

技巧:

1. 数组也可以用for in,这时 key 是数组索引

?
var  arr = [1, 2, 3, 4];
for  ( var  key in  arr) {
     console.log(key);
}

注意:关于 for in 是否有序,参考 w3help

只要 object 的 key 没有数字,遍历顺序和定义顺序是相同的;

如果有数字,会先把数字排好序,然后才是非数字部分,遍历顺序也是先数字,后非数字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值