您当前的位置: 首页 >  jquery

第二章 jQuery技术解密 (二)

发布时间:2013-12-28 16:14:00 ,浏览量:0

2.2.6 延续 -- 迭代器

在 jQuery 框架中,jQuery 对象是一个很奇怪的概念,具有多重身份,所以很多初学者一听说 jQuery 对象就感觉很是不解,误以为它是 John Resig 制造的新概念。我们可以对jQuery 对象进行如下分解。

第一,jQuery 对象是一个数据集合,它不是一个个体对象。因此,你无法直接使用 JavaScript 的方法来操作它。

第二,jQuery 对象实际上就是一个普通的对象,因为它是通过 new 运算符创建的一个新的实例对象。它可以继承原型方法或属性,同时也拥有 Object 类型的方法和属性。

第三,jQuery 对象包含数组特性,因为它赋值了数组元素,以数组结构存储返回的数据。我们可以以 JavaScript 的概念理解 jQuery 对象,例如下面的示例。

[html] view plain copy
  1. <scripttype="text/javascript">
  2. varjquery={//定义对象直接量
  3. name:"jQuery",//以属性方式存储信息
  4. value:"1.3.2"
  5. };
  6. jquery[0]="jQuery";//以数组方式存储信息
  7. jquery[1]="1.3.2";
  8. alert(jquery.name);//返回"jQuery"
  9. alert(jquery[0]);//返回"jQuery"
  10. this.length=0;//否则,设置实例的length属性值为0
  11. this.context=context;//设置实例的属性,返回选择范围
  12. returnthis;//返回当前实例
  13. }
  14. },
  15. html:function(val){//模仿jQuery框架中的html()方法,为匹配的每一个DOM元素插入html代码
  16. jQuery.each(this,function(val){//调用jQuery.each()工具函数,为每一个DOM元素执行回调函数
  17. this.innerHTML=val;
  18. },val);
  19. },
  20. jquery:"1.3.2",//原型属性
  21. size:function(){//原型方法
  22. returnthis.length;
  23. }
  24. };
  25. jQuery.fn.init.prototype=jQuery.fn;//使用jQuery的原型对象覆盖init的原型对象
  26. //扩展jQuery工具函数
  27. jQuery.each=function(object,callback,args){
  28. for(vari=0;i<object.length;i++){
  29. callback.call(object[i],args);
  30. }
  31. returnobject;
  32. };
  33. $("div").html("测试代码");
  34. // 扩展 jQuery 对象方法

    show: function(speed, callback){},

    hide: function(speed, callback){},

    toggle: function(fn, fn2){},

    fadeTo: function(speed, to, callback){},

    animate: function(prop, speed, easing, callback){},

    stop: function(clearQueue, gotoEnd){}

    });

    这样做的好处是什么呢?

    extend() 函数能够方便用户快速扩展 jQuery 框架的功能,但是不会破坏 jQuery 框架的原型结构,从而避免后期人工手动添加工具函数或者方法破坏 jQuery 框架的单纯性,同时也方便管理。如果不需要某个插件,只需要简单地删除即可,而不需要在 jQuery 框架源代码中去筛选和删除。

    extend() 函数的功能实现起来也很简单,它只是把指定对象的方法复制给 jQuery 对象或者 jQuery.prototype 对象。例如,在下面的示例中,我们为 jQuery 类和原型定义了一个扩展功能的函数 extend() ,该函数的功能很简单,它能够把指定参数对象包含的所有属性复制给 jQuery 或者 jQuery.prototype 对象,这样就可以在应用中随时调用它,并动态扩展 jQuery 对象的方法。

    [html] view plain copy
    1. <div>
    2. this.length=0;//否则,设置实例的length属性值为0
    3. this.context=context;//设置实例的属性,返回选择范围
    4. returnthis;//返回当前实例
    5. }
    6. },
    7. jquery:"1.3.2",//原型属性
    8. size:function(){//原型方法
    9. returnthis.length;
    10. }
    11. };
    12. jQuery.fn.init.prototype=jQuery.fn;//使用jQuery的原型对象覆盖init的原型对象
    13. //jQuery功能扩展函数
    14. jQuery.extend=jQuery.fn.extend=function(obj){
    15. for(varpropinobj){
    16. this[prop]=obj[prop];
    17. }
    18. returnthis;
    19. };
    20. //扩展jQuery对象方法
    21. jQuery.fn.extend({
    22. test:function(){
    23. alert("测试扩展功能");
    24. }
    25. });
    26. //测试代码
    27. $("div").test();
    28. type: "GET",

      url: "test.js",

      dataType: "script"

      });

      使用对象直接量作为参数进行传递,方便参数管理。当方法或者函数的参数长度不固定时,使用对象直接量作为参数存在很多优势。例如,对于下面的用法,ajax()函数就需要进行更加复杂的参数排查和过滤。

      $.ajax("GET", "test.js", "script");

      如果 ajax() 函数的参数长度是固定的,且是必须的,那么通过这种方式进行传递也就无所谓了,但是如果参数的个数和排序是动态的,那么使用 $.ajax("GET", "test.js", "script"); 这种方法是无法处理的。而 jQuery 框架的很多方法都包含大量的参数,且都是可选的,位置也没有固定要求,所以使用对象直接量是惟一的解决方法。

      使用对象直接量作为参数传递的载体,这里就涉及参数处理问题。如何解析并提出参数?如何处理参数和默认值?我们可以通过下面的方法来实现。

      [html] view plain copy
      1. <scripttype="text/javascript">
      2. var$=jQuery=function(selector,context){//定义类
      3. returnnewjQuery.fn.init(selector,context);//返回选择器的实例
      4. };
      5. jQuery.fn=jQuery.prototype={//jQuery类的原型对象
      6. init:function(selector,context){//定义选择器构造器
      7. selector=selector||document;//设置默认值为document
      8. context=context||document;//设置默认值为document
      9. if(selector.nodeType){//如果选择符为节点对象
      10. this[0]=selector;//把参数节点传递给实例对象的数组
      11. this.length=1;//并设置实例对象的length属性,定义包含的元素个数
      12. this.context=selector;//设置实例的属性,返回选择范围
      13. returnthis;//返回当前实例
      14. }
      15. if(typeofselector==="string"){//如果选择符是字符串
      16. vare=context.getElementsByTagName(selector);//获取指定名称的元素
      17. for(vari=0;i<e.length;i++){//遍历元素集合,并把所有元素填入到当前实例数组中
      18. this[i]=e[i];
      19. }
      20. this.length=e.length;//设置实例的length属性,即定义包含的元素个数
      21. this.context=context;//设置实例的属性,返回选择范围
      22. returnthis;//返回当前实例
      23. }else{
      24. this.length=0;//否则,设置实例的length属性值为0
      25. this.context=context;//设置实例的属性,返回选择范围
      26. returnthis;//返回当前实例
      27. }
      28. },
      29. setOptions:function(options){
      30. this.options={//方法的默认值,可以扩展
      31. StartColor:"#000",
      32. EndColor:"#DDC",
      33. Step:20,
      34. Speed:10
      35. };
      36. jQuery.extend(this.options,options||{});//如果传递参数,则覆盖原默认参数
      37. },
      38. jquery:"1.3.2",//原型属性
      39. size:function(){//原型方法
      40. returnthis.length;
      41. }
      42. };
      43. jQuery.fn.init.prototype=jQuery.fn;//使用jQuery的原型对象覆盖init的原型对象
      44. jQuery.extend=jQuery.fn.extend=function(destination,source){//重新定义extend()函数
      45. for(varpropertyinsource){
      46. destination[property]=source[property];
      47. }
      48. returndestination;
      49. };
      50. returnnewjQuery.fn.init(selector,context);
      51. };
      52. alert("观察我什么时候出现");

        })();

        这是一个典型的匿名函数基本形式。为什么要用到匿名函数呢?

        这时就要进入正题了,如果希望自己的 jQuery 框架与其他任何代码完全隔离开来,也就是说如果你想把 jQuery 装在一个封闭空间中,不希望暴露内部信息,也不希望别的代码随意访问,匿名函数就是一种最好的封闭方式。此时我们只需要提供接口,就可以方便地与外界进行联系。例如,在下面的示例中分别把 f1 函数放在一个匿名函数中,而把 f2 函数放在全局作用域中。可以发现,全局作用域中的 f2 函数可以允许访问,而匿名函数中的 f1 函数是禁止外界访问的。

        [html] view plain copy
        1. <scripttype="text/javascript">
        2. (function(){
        3. functionf1(){
        4. return"f1()";
        5. }
        6. })();
        7. functionf2(){
        8. return"f2()";
        9. }
        10. alert(f2());//返回"f2()"
        11. alert(f1());//抛出异常,禁止访问
        12. var
        13. window=this,
        14. undefined,
        15. _jQuery=window.jQuery,//暂存jQuery变量内容
        16. _$=window.$,//暂存$变量内容
        17. jQuery=window.jQuery=window.$=function(selector,context){
        18. returnnewjQuery.fn.init(selector,context);
        19. },
        20. quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
        21. isSimple=/^.[^:#\[\.,]*$/;
        22. jQuery.fn=jQuery.prototype={
        23. init:function(selector,context){//定义选择器构造器
        24. selector=selector||document;//设置默认值为document
        25. context=context||document;//设置默认值为document
        26. if(selector.nodeType){//如果选择符为节点对象
        27. this[0]=selector;//把参数节点传递给实例对象的数组
        28. this.length=1;//并设置实例对象的length属性,定义包含的元素个数
        29. this.context=selector;//设置实例的属性,返回选择范围
        30. returnthis;//返回当前实例
        31. }
        32. if(typeofselector==="string"){//如果选择符是字符串
        33. vare=context.getElementsByTagName(selector);//获取指定名称的元素
        34. for(vari=0;i<e.length;i++){//遍历元素集合,并把所有元素填入到当前实例数组中
        35. this[i]=e[i];
        36. }
        37. this.length=e.length;//设置实例的length属性,即定义包含的元素个数
        38. this.context=context;//设置实例的属性,返回选择范围
        39. returnthis;//返回当前实例
        40. }else{
        41. this.length=0;//否则,设置实例的length属性值为0
        42. this.context=context;//设置实例的属性,返回选择范围
        43. returnthis;//返回当前实例
        44. }
        45. },
        46. setOptions:function(options){
        47. this.options={//方法的默认值,可以扩展
        48. StartColor:"#000",
        49. EndColor:"#DDC",
        50. Step:20,
        51. Speed:10
        52. };
        53. jQuery.extend(this.options,options||{});//如果传递参数,则覆盖原默认参数
        54. },
        55. jquery:"1.3.2",//原型属性
        56. size:function(){//原型方法
        57. returnthis.length;
        58. }
        59. };
        60. jQuery.fn.init.prototype=jQuery.fn;//使用jQuery的原型对象覆盖init的原型对象
        61. jQuery.extend=jQuery.fn.extend=function(destination,source){//重新定义extend()函数
        62. for(varpropertyinsource){
        63. destination[property]=source[property];
        64. }
        65. returndestination;
        66. };
        67. })();
关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    108697博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0562s