jquery内核及实现原理(二)--选择,迭代,命名空间,继承,参数

 5)成熟--选择器
jquery返回的是一个类数组对象,也就是说有数组的长度和下标,但是没有数组的方法.

<div>11</div>
  <div>22</div>
  <div>33</div>
  <div>44</div>
  <div>55</div>
    <script type="text/javascript">
      var $ = jquery = function(selector,context){
           return new jquery.fn.init(selector,context);
      }
      jquery.fn = jquery.protopyte = {  //扩展原型对象
          init : function(selector,context){
            selector = selector || document;  //如果第一个参数有值,则selector为参数值,否则为这个页面的document对象
            context = context || document;
            if(selector.nodeType){           //nodeType属性表示节点类型,如果是string类型的,则是undefined,其他比较重要的值为元素element为1,文档document为9等
               this[0] = selector;           //如果没传参数,则selector为document对象,selector.nodeType为9
               this.length = 1; 
               this.context = selector;
               return this;
            }
            if(typeof(selector) === "string"){    //如果传入的值是string类型的
              var e = context.getElementsByTagName(selector);   //获取传入值的所有节点
              for(var i = 0;i< e.length;i++){
                 this[i]=e[i];
              }
              this.length = e.length;
              this.context = context;
              return this;
            }else{
              this.length = 0;
              this.context = context;
              return this;
            } 
          },
          length : "100",
          jquery : "1.9.0",
          size : function(){
              return this.length;
          }
      }
      jquery.fn.init.prototype = jquery.fn;
      alert($("div").size());    //打印出来是5
    </script>


上述代码基本有了框架中$("div")语法的功能,他可以选择指定范围的div元素,并且调用size()方法返回长度.

6)延伸--迭代器
jquery提供了一个each工具函数用来迭代,下面用html()方法来模拟迭代:

<div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
    <script type="text/javascript">
      var $ = jquery = function(selector,context){
           return new jquery.fn.init(selector,context);
      }
      jquery.fn = jquery.protopyte = {  //扩展原型对象
          init : function(selector,context){
            selector = selector || document;  //如果第一个参数有值,则selector为参数值,否则为这个页面的document对象
            context = context || document;
            if(selector.nodeType){           //nodeType属性表示节点类型,如果是string类型的,则是undefined,其他比较重要的值为元素element为1,文档document为9等
               this[0] = selector;           //如果没传参数,则selector为document对象,selector.nodeType为9
               this.length = 1; 
               this.context = selector;
               return this;
            }
            if(typeof(selector) === "string"){    //如果传入的值是string类型的
              var e = context.getElementsByTagName(selector);   //获取传入值的所有节点
              for(var i = 0;i< e.length;i++){
                 this[i]=e[i];
              }
              this.length = e.length;
              this.context = context;
              return this;
            }else{
              this.length = 0;
              this.context = context;
              return this;
            } 
          },
          length : "100",
          jquery : "1.9.0",
          size : function(){
              return this.length;
          },
          html : function(val){
             jquery.each(this,function(val){
  this.innerHTML = val;
  },val);    
      }
      }
      jquery.fn.init.prototype = jquery.fn;
      jquery.each = function(object,callback,args){
  for(var i=0;i<object.length;i++){
            callback.call(object[i],args);
         }
     return object;
      }
      $("div").html("test"); //每个div展示test
    </script>

 
  7延伸--功能扩展
jquery框架用extend()函数来快速扩展jquery的功能,这样做的好处是不会破坏jquery框架,方便管理,如果不需要某个插件,直接删除就可以了,而不必侵入jquery框架里面去筛选删除.
 

<body>
  <div></div>
    <script type="text/javascript">
      var $ = jquery = function(selector,context){
           return new jquery.fn.init(selector,context);
      }
      jquery.fn = jquery.protopyte = {  //扩展原型对象
          init : function(selector,context){
            selector = selector || document;
            context = context || document;
            if(selector.nodeType){
               this[0] = selector;
               this.length = 1;
               this.context = selector;
               return this;
            }
            if(typeof(selector) == "string"){
              var e = context.getElementsByTagName(selector);
              for(var i = 0;i< e.length;i++){
                 this[i]=e[i];
              }
              this.length = e.length;
              this.context = context;
              return this;
            }else{
              this.length = 0;
              this.context = context;
              return this;
            } 
          },
          length : "3",
          jquery : "1.9.0",
          size : function(){
              return this.length;
          }
      }
      jquery.fn.init.prototype = jquery.fn;
      jquery.extend = jquery.fn.extend = function(obj){
        for(var prop in obj){
           this[prop] = obj[prop];
        }
        return this;
      }
      jquery.fn.extend({
         test : function(){
           alert("这是测试方法");
         }
      })

      $("div").test();
    </script>
  </body>

当然jquery的extend方法要复杂很多,不仅能扩展,还能实现对象合并等方法.

8延续--参数处理
jquery在extend()里处理参数,里面定义了一个options,有初始值,如果外界传过来的值在里面有定义,就覆盖,否则就多加一个参数.

9涅槃--名字空间
jquery用闭包的方式来避免名称和其他框架冲突,也防止了其他框架调用jquery方法,具体做法是:
(function(){
})()
因为$并不是jquery的专利,其他框架也会用到这个变量,所以jquery用noConflict(jquery1.9.0里的方法,其他版本可能是noConfilit())方法来避免:

noConflict: function( deep ) {
  if ( window.$ === jQuery ) {
   window.$ = _$;
  }

  if ( deep && window.jQuery === jQuery ) {
   window.jQuery = _jQuery;
  }

  return jQuery;
 }

 使用的时候要写成例如jQuery("div").test()

相关推荐