• jQuery.data() 的实现方式,jQuery16018518865841457738的由来,jQuery后边一串数字的由来


    原文地址: http://xxing22657-yahoo-com-cn.iteye.com/blog/1042440

    jQuery.data() 的实现方式

        jQuery.data() 的作用是为普通对象或 DOM Element 附加(及获取)数据。
        下面将分三个部分分析其实现方式:
        1. 用name和value为对象附加数据;即传入三个参数,第一个参数为需要附加数据的对象,第二个参数为数据的名称,第三个参数为数据的值。当然,只是获取值的话,也可以不传入第三个参数。
        2. 用另一个对象为对象附加数据;即传入两个参数,第一个参数为需要附加的数据对象(我们称之为“obj”),第二个参数也是一个对象(我们称之为“another”);“another”中包含的键值对将会被复制到 “obj” 的数据缓存(我们称之为“cache”)中。
        3. 为 DOM Element 附加数据;DOM Element 也是一种 Object ,但 IE6、IE7 对直接附加在 DOM Element 上的对象的垃圾回收存在问题;因此我们将这些数据存放在全局缓存(我们称之为“globalCache”)中,即 “globalCache” 包含了多个 DOM Element 的 “cache”,并在 DOM Element 上添加一个属性,存放 “cache” 对应的 uid 。

    用name和value为对象附加数据

        使用 jQuery.data() 为普通对象附加数据时,其本质是将一个 “cache” 附加到了对象上,并使用了一个特殊的属性名称。
        存放数据的 “cache” 也是一个 object,我们为 “obj” 附加的数据实际上成为了 “cache” 的属性。而 “cache” 又是 “obj” 的一个属性,在 jQuery 1.6中,这个属性的名称是 “jQuery16”加上一个随机数(如下面提到的 “jQuery16018518865841457738” )。

        我们可以用下面的代码来测试 jQuery.data() 的功能:

    Html代码  收藏代码
    1. <script type="text/javascript" src="jquery.js"></script>  
    2. <script>  
    3. obj = {};  
    4. $.data(obj, 'name', 'value');  
    5. document.write("$.data(obj, 'name') = " + $.data(obj, 'name') + '<br />');  
    6.   
    7. for (var key in obj) {  
    8.     document.write("obj." + key + '.name = ' + obj[key].name);  
    9. }  
    10. </script>  
    <script type="text/javascript" src="jquery.js"></script>
    <script>
    obj = {};
    $.data(obj, 'name', 'value');
    document.write("$.data(obj, 'name') = " + $.data(obj, 'name') + '<br />');
    
    for (var key in obj) {
    	document.write("obj." + key + '.name = ' + obj[key].name);
    }
    </script>
    

        显示结果为:
    Html代码  收藏代码
    1. $.data(obj, 'name') = value  
    2. obj.jQuery16018518865841457738.name = value  
    $.data(obj, 'name') = value
    obj.jQuery16018518865841457738.name = value
    

        在这段代码中,我们首先在 “obj” 上附加了一个属性(名称为“name”,值为“value”),然后通过 $.data(obj, 'name') 来获取所附加的数据。为了深入了解其中的实现机制,我们有使用了一个循环来获取 “obj” 的属性,实际上是取出了在 “obj” 上附加的 “cache”对象。

        可以看到,jQuery.data() 实际上为 “obj” 附加到了名为 “jQuery16018518865841457738” (这个名称是随机的)的对象,也就是 “cache” 上。用 jquery.data() 方式为对象附加的属性实际上成为了这个 “cache” 的属性。

        我们可以用下面的代码实现类似的功能:

    Javascript代码  收藏代码
    1. $ = function() {  
    2.     var expando = "jQuery" + ("1.6" + Math.random()).replace(/D/g, '');  
    3.   
    4.     function getData(cache, name) {  
    5.         return cache[name];  
    6.     }  
    7.   
    8.     function setData(cache, name, value) {  
    9.         cache[name] = value;  
    10.     }  
    11.   
    12.     function getCache(obj) {  
    13.         obj[expando] = obj[expando] || {};  
    14.         return obj[expando];  
    15.     }  
    16.   
    17.     return {  
    18.         data : function(obj, name, value) {  
    19.             var cache = getCache(obj);  
    20.   
    21.             if (value === undefined) {  
    22.                 return getData(cache, name);  
    23.             } else {  
    24.                 setData(cache, name, value);  
    25.             }  
    26.         }  
    27.     }  
    28. }();  
    $ = function() {
        var expando = "jQuery" + ("1.6" + Math.random()).replace(/D/g, '');
    
        function getData(cache, name) {
            return cache[name];
        }
    
        function setData(cache, name, value) {
            cache[name] = value;
        }
    
        function getCache(obj) {
            obj[expando] = obj[expando] || {};
            return obj[expando];
        }
    
        return {
            data : function(obj, name, value) {
                var cache = getCache(obj);
    
                if (value === undefined) {
                    return getData(cache, name);
                } else {
                    setData(cache, name, value);
                }
            }
        }
    }();
    


        function 中的第一行代码定义了 “expando” ,即 "jQuery1.6" 加上一个随机数(0.xxxx),并将其中非数字的部分去掉;这种格式将在jQuery的其他地方用到,这里不做探讨;只需要知道这是一个特殊的名称,并且可以用于标识不同的页面(比如不同 iframe 中的 “expando” 就会有所不同)。

        接下来定义了获取数据的函数 getData(), 即从 “cache” 中获取一个属性;实际上也就是返回 cache[name] 。
        然后是 setData() 函数,用于设置 “cache” 的属性;实际上也就是设置 cache[name] 的值。
        之后是 getCache() , 获取 “obj” 上的 “cache”,即 obj[expando];如果 obj[expando] 为空,则进行初始化。
        最后公开了 data 方法,先根据传入的 “obj”,获取附加在 “obj” 上的 “cache”; 当传入两个参数时,调用 getData()方法;当传入三个参数时,则调用 setData() 方法。


    用另一个对象为对象附加数据

         除了以提供 name 和 value 的方式进行赋值,我们还可以直接传入另一个对象( “another” )作为参数。这种情况下,“another” 的属性名称和属性值将被视为多个键值对,从中提取的 “name” 和 “value” 都会被复制到目标对象的缓存中。

         功能测试代码如下:

    Html代码  收藏代码
    1. <script type="text/javascript" src="jquery.js"></script>  
    2. <script>  
    3. obj = {};  
    4. $.data(obj, {name1: 'value1', name2: 'value2'});  
    5.   
    6. document.write("$.data(obj, 'name1') = " + $.data(obj, 'name1')  + '<br />' );  
    7. document.write("$.data(obj, 'name2') = " + $.data(obj, 'name2') + '<br />');  
    8.   
    9. for (var key in obj) {  
    10.     document.write("obj." + key + '.name1 = ' + obj[key].name1 + '<br />');  
    11.     document.write("obj." + key + '.name2 = ' + obj[key].name2);  
    12. }  
    13. </script>  
    <script type="text/javascript" src="jquery.js"></script>
    <script>
    obj = {};
    $.data(obj, {name1: 'value1', name2: 'value2'});
    
    document.write("$.data(obj, 'name1') = " + $.data(obj, 'name1')  + '<br />' );
    document.write("$.data(obj, 'name2') = " + $.data(obj, 'name2') + '<br />');
    
    for (var key in obj) {
    	document.write("obj." + key + '.name1 = ' + obj[key].name1 + '<br />');
    	document.write("obj." + key + '.name2 = ' + obj[key].name2);
    }
    </script>
    


        显示结果如下:

    Html代码  收藏代码
    1. $.data(obj, 'name1') = value1  
    2. $.data(obj, 'name2') = value2  
    3. obj.jQuery1600233050178663064.name1 = value1  
    4. obj.jQuery1600233050178663064.name2 = value2  
    $.data(obj, 'name1') = value1
    $.data(obj, 'name2') = value2
    obj.jQuery1600233050178663064.name1 = value1
    obj.jQuery1600233050178663064.name2 = value2
    


        上面的测试代码中,我们先将一个带有两个键值对的 “another” 对象传入,然后分别用 $.data(obj, 'name1') 和 $.data(obj, 'name2') 获取附加的数据;同样,为了深入了解其中的机制,我们通过遍历 “obj” 的方式取出了隐藏的 “cache” 对象,并获得了 “cache” 对象的 “name1” 属性和 “name2” 属性的值。

        可以看到,jQuery.data() 实际上为 “obj” 附加了名为 “obj.jQuery1600233050178663064” 的对象,也就是 “cache” 上。用 jquery.data() 方式传入的键值对都被复制到了 “cache” 中。

        我们可以用下面的代码实现类似的功能:

    Javascript代码  收藏代码
    1. $ = function() {  
    2.     // Other codes ...  
    3.   
    4.     function setDataWithObject(cache, another) {  
    5.         for (var name in another) {  
    6.             cache[name] = another[name];  
    7.         }  
    8.     }  
    9.   
    10.     // Other codes ...  
    11.   
    12.     return {  
    13.         data : function(obj, name, value) {  
    14.             var cache = getCache(obj);  
    15.   
    16.             if (name instanceof Object) {  
    17.                 setDataWithObject(cache, name)  
    18.             } else if (value === undefined) {  
    19.                 return getData(cache, name);  
    20.             } else {  
    21.                 setData(cache, name, value);  
    22.             }  
    23.         }  
    24.     }  
    25. }();  
    $ = function() {
        // Other codes ...
    
        function setDataWithObject(cache, another) {
            for (var name in another) {
                cache[name] = another[name];
            }
        }
    
        // Other codes ...
    
        return {
            data : function(obj, name, value) {
                var cache = getCache(obj);
    
                if (name instanceof Object) {
                    setDataWithObject(cache, name)
                } else if (value === undefined) {
                    return getData(cache, name);
                } else {
                    setData(cache, name, value);
                }
            }
        }
    }();
    


        这段代码是在之前的代码的基础上进行修改的。首先增加了内部函数 setDataWithObject() ,这个函数的实现是遍历 “another” 的属性,并复制到 “cache” 中。
        然后,在对外开放的 data 函数中,先判断传入的第二个参数的名称,如果这个参数是一个 Object 类型的实例,则调用 setDataWithObject() 方法。


    为 DOM Element 附加数据

        由于 DOM Element 也是一种 Object,因此之前的方式也可以为 DOM Element 赋值;但考虑到 IE6、IE7 中垃圾回收的问题(不能有效回收 DOM Element 上附加的对象引用),jQuery采用了与普通对象有所不同的方式附加数据。

        测试代码如下:

    Html代码  收藏代码
    1. <div id="div_test" />  
    2.   
    3. <script type="text/javascript" src="data.js"></script>  
    4. <script>  
    5. window.onload = function() {  
    6.     div = document.getElementById('div_test');  
    7.     $.data(div, 'name', 'value');  
    8.     document.write($.data(div, 'name'));  
    9. }  
    10. </script>  
    <div id="div_test" />
    
    <script type="text/javascript" src="data.js"></script>
    <script>
    window.onload = function() {
    	div = document.getElementById('div_test');
    	$.data(div, 'name', 'value');
    	document.write($.data(div, 'name'));
    }
    </script>
    


        显示结果如下:

    Html代码  收藏代码
    1. value  
    value
    


        测试代码中,首先通过 document.getElementById 方法获取了一个 DOM Element (当然,也可以用 jQuery 的选择器),然后在这个 DOM Element 上附加了一个属性,随后就从 DOM Element 上取出了附加的属性并输出。

        因为考虑到 IE6、IE7 对 DOM Element 上的对象引用的垃圾回收存在问题,我们不会直接在 DOM Element 上附加对象;而是使用全局cache,并在 DOM Element 上附加一个 uid。

        实现方式如下:
    Javascript代码  收藏代码
    1. $ = function() {  
    2.     var expando = "jQuery" + ("1.6" + Math.random()).replace(/D/g, '');  
    3.     var globalCache = {};  
    4.     var uuid = 0;  
    5.   
    6.     // Other codes ...  
    7.   
    8.     function getCache(obj) {  
    9.         if (obj.nodeType) {  
    10.             var id = obj[expando] = obj[expando] || ++uuid;  
    11.             globalCache[id] = globalCache[id] || {};  
    12.             return globalCache[id];  
    13.         } else {  
    14.             obj[expando] = obj[expando] || {};  
    15.             return obj[expando];  
    16.         }  
    17.     }  
    18.   
    19.     // Other codes ...  
    20. }();  
    $ = function() {
        var expando = "jQuery" + ("1.6" + Math.random()).replace(/D/g, '');
        var globalCache = {};
        var uuid = 0;
    
        // Other codes ...
    
        function getCache(obj) {
            if (obj.nodeType) {
                var id = obj[expando] = obj[expando] || ++uuid;
                globalCache[id] = globalCache[id] || {};
                return globalCache[id];
            } else {
                obj[expando] = obj[expando] || {};
                return obj[expando];
            }
        }
    
        // Other codes ...
    }();
    


        这段代码与之前的代码相比,增加了 globalCache 和 uuid,并修改了 getCache() 方法。

        globalCache 对象用于存放附加到 DOM Element 上的 “cache”,可以视为 “cache” 的“容器”。uuid 表示 “cache” 对应的唯一标识,是唯一且自增长的。uuid 或被存放在 DOM Element 的 “expando” 属性中。
        getCache() 函数中增加了一个判断,即 “obj” 具有 “nodeType” 属性,就认为这是一个 DOM Element;这种情况下,就先取出附加在 “obj” 上的 id ,即 obj[expando] ;如果 obj[expando] 未定义,则先用 ++uuid 对其进行初始化;取出 id 之后,就到 globalCache 中找到对应的 “cache” ,即 globalCache[id], 并返回。

        到此为止,jQuery.data() 函数的实现就介绍完了;但是,这里还有一个需要思考的问题:为什不都统一用 “globalCache” 存储,而要将 “cache” 直接附加到普通对象上?我认为这应该是一种性能优化的方式,毕竟少一个引用的层次,存取速度应该会略快一些。 jQuery 中这刻意优化的地方非常多,在许多原本可以统一处理的对方都进行了特殊处理。但这在一定程度上,也造成了阅读源码的障碍。当然这是作者(及其他代码贡献者)本身的编程哲学,这里就不加评论了。
    1. <script type="text/javascript" src="jquery.js"></script> 
    2. <script> 
    3. obj = {}; 
    4. $.data(obj, 'name', 'value'); 
    5. document.write("$.data(obj, 'name') = " + $.data(obj, 'name') + '<br />'); 
    6.  
    7. for (var key in obj) { 
    8.     document.write("obj." + key + '.name = ' + obj[key].name); 
    9. </script> 
    <script type="text/javascript" src="jquery.js"></script>
    <script>
    obj = {};
    $.data(obj, 'name', 'value');
    document.write("$.data(obj, 'name') = " + $.data(obj, 'name') + '<br />');
    
    for (var key in obj) {
    	document.write("obj." + key + '.name = ' + obj[key].name);
    }
    </script>
    


        显示结果为:

    Html代码  收藏代码
    1. $.data(obj, 'name') = value 
    2. obj.jQuery16018518865841457738.name = value 
    $.data(obj, 'name') = value
    obj.jQuery16018518865841457738.name = value
    


        在这段代码中,我们首先在 “obj” 上附加了一个属性(名称为“name”,值为“value”),然后通过 $.data(obj, 'name') 来获取所附加的数据。为了深入了解其中的实现机制,我们有使用了一个循环来获取 “obj” 的属性,实际上是取出了在 “obj” 上附加的 “cache”对象。

        可以看到,jQuery.data() 实际上为 “obj” 附加到了名为 “jQuery16018518865841457738” (这个名称是随机的)的对象,也就是 “cache” 上。用 jquery.data() 方式为对象附加的属性实际上成为了这个 “cache” 的属性。

        我们可以用下面的代码实现类似的功能:

    Javascript代码  收藏代码
    1. $ = function() { 
    2.     var expando = "jQuery" + ("1.6" + Math.random()).replace(/D/g, ''); 
    3.  
    4.     function getData(cache, name) { 
    5.         return cache[name]; 
    6.     } 
    7.  
    8.     function setData(cache, name, value) { 
    9.         cache[name] = value; 
    10.     } 
    11.  
    12.     function getCache(obj) { 
    13.         obj[expando] = obj[expando] || {}; 
    14.         return obj[expando]; 
    15.     } 
    16.  
    17.     return
    18.         data : function(obj, name, value) { 
    19.             var cache = getCache(obj); 
    20.  
    21.             if (value === undefined) { 
    22.                 return getData(cache, name); 
    23.             } else
    24.                 setData(cache, name, value); 
    25.             } 
    26.         } 
    27.     } 
    28. }(); 
    $ = function() {
        var expando = "jQuery" + ("1.6" + Math.random()).replace(/D/g, '');
    
        function getData(cache, name) {
            return cache[name];
        }
    
        function setData(cache, name, value) {
            cache[name] = value;
        }
    
        function getCache(obj) {
            obj[expando] = obj[expando] || {};
            return obj[expando];
        }
    
        return {
            data : function(obj, name, value) {
                var cache = getCache(obj);
    
                if (value === undefined) {
                    return getData(cache, name);
                } else {
                    setData(cache, name, value);
                }
            }
        }
    }();
    



        function 中的第一行代码定义了 “expando” ,即 "jQuery1.6" 加上一个随机数(0.xxxx),并将其中非数字的部分去掉;这种格式将在jQuery的其他地方用到,这里不做探讨;只需要知道这是一个特殊的名称,并且可以用于标识不同的页面(比如不同 iframe 中的 “expando” 就会有所不同)。

        接下来定义了获取数据的函数 getData(), 即从 “cache” 中获取一个属性;实际上也就是返回 cache[name] 。
        然后是 setData() 函数,用于设置 “cache” 的属性;实际上也就是设置 cache[name] 的值。
        之后是 getCache() , 获取 “obj” 上的 “cache”,即 obj[expando];如果 obj[expando] 为空,则进行初始化。
        最后公开了 data 方法,先根据传入的 “obj”,获取附加在 “obj” 上的 “cache”; 当传入两个参数时,调用 getData()方法;当传入三个参数时,则调用 setData() 方法。

    用另一个对象为对象附加数据


         除了以提供 name 和 value 的方式进行赋值,我们还可以直接传入另一个对象( “another” )作为参数。这种情况下,“another” 的属性名称和属性值将被视为多个键值对,从中提取的 “name” 和 “value” 都会被复制到目标对象的缓存中。

         功能测试代码如下:

    Html代码  收藏代码
    1. <script type="text/javascript" src="jquery.js"></script> 
    2. <script> 
    3. obj = {}; 
    4. $.data(obj, {name1: 'value1', name2: 'value2'}); 
    5.  
    6. document.write("$.data(obj, 'name1') = " + $.data(obj, 'name1')  + '<br />' ); 
    7. document.write("$.data(obj, 'name2') = " + $.data(obj, 'name2') + '<br />'); 
    8.  
    9. for (var key in obj) { 
    10.     document.write("obj." + key + '.name1 = ' + obj[key].name1 + '<br />'); 
    11.     document.write("obj." + key + '.name2 = ' + obj[key].name2); 
    12. </script> 
    <script type="text/javascript" src="jquery.js"></script>
    <script>
    obj = {};
    $.data(obj, {name1: 'value1', name2: 'value2'});
    
    document.write("$.data(obj, 'name1') = " + $.data(obj, 'name1')  + '<br />' );
    document.write("$.data(obj, 'name2') = " + $.data(obj, 'name2') + '<br />');
    
    for (var key in obj) {
    	document.write("obj." + key + '.name1 = ' + obj[key].name1 + '<br />');
    	document.write("obj." + key + '.name2 = ' + obj[key].name2);
    }
    </script>
    



        显示结果如下:

    Html代码  收藏代码
    1. $.data(obj, 'name1') = value1 
    2. $.data(obj, 'name2') = value2 
    3. obj.jQuery1600233050178663064.name1 = value1 
    4. obj.jQuery1600233050178663064.name2 = value2 
    $.data(obj, 'name1') = value1
    $.data(obj, 'name2') = value2
    obj.jQuery1600233050178663064.name1 = value1
    obj.jQuery1600233050178663064.name2 = value2
    



        上面的测试代码中,我们先将一个带有两个键值对的 “another” 对象传入,然后分别用 $.data(obj, 'name1') 和 $.data(obj, 'name2') 获取附加的数据;同样,为了深入了解其中的机制,我们通过遍历 “obj” 的方式取出了隐藏的 “cache” 对象,并获得了 “cache” 对象的 “name1” 属性和 “name2” 属性的值。

        可以看到,jQuery.data() 实际上为 “obj” 附加了名为 “obj.jQuery1600233050178663064” 的对象,也就是 “cache” 上。用 jquery.data() 方式传入的键值对都被复制到了 “cache” 中。

        我们可以用下面的代码实现类似的功能:

    Javascript代码  收藏代码
    1. $ = function() { 
    2.     // Other codes ... 
    3.  
    4.     function setDataWithObject(cache, another) { 
    5.         for (var name in another) { 
    6.             cache[name] = another[name]; 
    7.         } 
    8.     } 
    9.  
    10.     // Other codes ... 
    11.  
    12.     return
    13.         data : function(obj, name, value) { 
    14.             var cache = getCache(obj); 
    15.  
    16.             if (name instanceof Object) { 
    17.                 setDataWithObject(cache, name) 
    18.             } else if (value === undefined) { 
    19.                 return getData(cache, name); 
    20.             } else
    21.                 setData(cache, name, value); 
    22.             } 
    23.         } 
    24.     } 
    25. }(); 
    $ = function() {
        // Other codes ...
    
        function setDataWithObject(cache, another) {
            for (var name in another) {
                cache[name] = another[name];
            }
        }
    
        // Other codes ...
    
        return {
            data : function(obj, name, value) {
                var cache = getCache(obj);
    
                if (name instanceof Object) {
                    setDataWithObject(cache, name)
                } else if (value === undefined) {
                    return getData(cache, name);
                } else {
                    setData(cache, name, value);
                }
            }
        }
    }();
    



        这段代码是在之前的代码的基础上进行修改的。首先增加了内部函数 setDataWithObject() ,这个函数的实现是遍历 “another” 的属性,并复制到 “cache” 中。
        然后,在对外开放的 data 函数中,先判断传入的第二个参数的名称,如果这个参数是一个 Object 类型的实例,则调用 setDataWithObject() 方法。

    为 DOM Element 附加数据


        由于 DOM Element 也是一种 Object,因此之前的方式也可以为 DOM Element 赋值;但考虑到 IE6、IE7 中垃圾回收的问题(不能有效回收 DOM Element 上附加的对象引用),jQuery采用了与普通对象有所不同的方式附加数据。

        测试代码如下:

    Html代码  收藏代码
    1. <div id="div_test" /> 
    2.  
    3. <script type="text/javascript" src="data.js"></script> 
    4. <script> 
    5. window.onload = function() { 
    6.     div = document.getElementById('div_test'); 
    7.     $.data(div, 'name', 'value'); 
    8.     document.write($.data(div, 'name')); 
    9. </script> 
    <div id="div_test" />
    
    <script type="text/javascript" src="data.js"></script>
    <script>
    window.onload = function() {
    	div = document.getElementById('div_test');
    	$.data(div, 'name', 'value');
    	document.write($.data(div, 'name'));
    }
    </script>
    



        显示结果如下:

    Html代码  收藏代码
    1. value 
    value
    



        测试代码中,首先通过 document.getElementById 方法获取了一个 DOM Element (当然,也可以用 jQuery 的选择器),然后在这个 DOM Element 上附加了一个属性,随后就从 DOM Element 上取出了附加的属性并输出。

        因为考虑到 IE6、IE7 对 DOM Element 上的对象引用的垃圾回收存在问题,我们不会直接在 DOM Element 上附加对象;而是使用全局cache,并在 DOM Element 上附加一个 uid。

        实现方式如下:

    Javascript代码  收藏代码
    1. $ = function() { 
    2.     var expando = "jQuery" + ("1.6" + Math.random()).replace(/D/g, ''); 
    3.     var globalCache = {}; 
    4.     var uuid = 0; 
    5.  
    6.     // Other codes ... 
    7.  
    8.     function getCache(obj) { 
    9.         if (obj.nodeType) { 
    10.             var id = obj[expando] = obj[expando] || ++uuid; 
    11.             globalCache[id] = globalCache[id] || {}; 
    12.             return globalCache[id]; 
    13.         } else
    14.             obj[expando] = obj[expando] || {}; 
    15.             return obj[expando]; 
    16.         } 
    17.     } 
    18.  
    19.     // Other codes ... 
    20. }(); 
    $ = function() {
        var expando = "jQuery" + ("1.6" + Math.random()).replace(/D/g, '');
        var globalCache = {};
        var uuid = 0;
    
        // Other codes ...
    
        function getCache(obj) {
            if (obj.nodeType) {
                var id = obj[expando] = obj[expando] || ++uuid;
                globalCache[id] = globalCache[id] || {};
                return globalCache[id];
            } else {
                obj[expando] = obj[expando] || {};
                return obj[expando];
            }
        }
    
        // Other codes ...
    }();
    



        这段代码与之前的代码相比,增加了 globalCache 和 uuid,并修改了 getCache() 方法。

        globalCache 对象用于存放附加到 DOM Element 上的 “cache”,可以视为 “cache” 的“容器”。uuid 表示 “cache” 对应的唯一标识,是唯一且自增长的。uuid 或被存放在 DOM Element 的 “expando” 属性中。
        getCache() 函数中增加了一个判断,即 “obj” 具有 “nodeType” 属性,就认为这是一个 DOM Element;这种情况下,就先取出附加在 “obj” 上的 id ,即 obj[expando] ;如果 obj[expando] 未定义,则先用 ++uuid 对其进行初始化;取出 id 之后,就到 globalCache 中找到对应的 “cache” ,即 globalCache[id], 并返回。

        到此为止,jQuery.data() 函数的实现就介绍完了;但是,这里还有一个需要思考的问题:为什不都统一用 “globalCache” 存储,而要将 “cache” 直接附加到普通对象上?我认为这应该是一种性能优化的方式,毕竟少一个引用的层次,存取速度应该会略快一些。 jQuery 中这刻意优化的地方非常多,在许多原本可以统一处理的对方都进行了特殊处理。但这在一定程度上,也造成了阅读源码的障碍。当然这是作者(及其他代码贡献者)本身的编程哲学,这里就不加评论了。

  • 相关阅读:
    338. 比特位计数
    300.最长上升子序列
    git 钩子服务代码
    thinkphp5.1 封装文件上传模块
    Theano 基础
    使用anaconda和pycharm搭建多python本版的开发环境
    GIT常用命令
    Thinkphp 获取数据表随机值
    在Windows中利用.bat提交git代码到不同分支
    Windows .bat 常量
  • 原文地址:https://www.cnblogs.com/suizhikuo/p/9195906.html
Copyright © 2020-2023  润新知