zoukankan      html  css  js  c++  java
  • 细说jQuery原型的创建和实现原理,并用实例简单模仿

         在解析jQuery实现机理之前,我们先总结一下几点知识,这些都是我学习路上遇到的坑,我跌倒过很多次,现在把它补上:

         1)自定义构造函数,如下例:

             function person(){
                  this.name="aa";
               }
               person();
               console.log(window.name);//aa
    

      这个函数是为了证明全局环境下的执行上下文是window(全局)对象,如上例无意间会创建一个全局变量name,因为this指向window对象。其实不通过new构造,执行函数内部的“this.属性”会成为其父级对象域内的属性;通过new构造,函数执行上下文会变成一个空的上下文,这个上下文代表了新生成的实例。总言之,this指向当前调用它的对象,更精确地说,this指向它的执行上下文。

         2)利用对象[基本数据类型]格式创建的属性只能通过对象[基本数据类型]的格式访问;

         3)在函数的内部有函数定义时为了避免this指针的指向混乱,在首函数的内部声明"var self=this;",用self来表示此函数的this指针,避免与其他函数内部this指针混淆;

         现在来看jQuery的实现机制:

        以下是jQuery1.61内的代码:

    var jQuery = function( selector, context ) {
            // The jQuery object is actually just the init constructor 'enhanced'
            return new jQuery.fn.init( selector, context, rootjQuery );
        },
        ...
        class2type = {};
         
    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function(selector, context, rootjQuery){
        }
    }
     
    // Give the init function the jQuery prototype for later instantiation
    jQuery.fn.init.prototype = jQuery.fn;
    

      提炼总结上面这段代码:jQuery.fn.init是个构造函数,因为jQuery.fn.init.prototype=jQuery.prototype,所以jQuery.fn.init的实例对象也是jQuery的实例对象,意指jQuery.fn.init构造的实例对象,可以访问jQuery.fn.init.prototype的属性及函数,也可以访问jQuery.prototype的属性及函数。

        现在我们来遵循这个思路写上这样的代码:

                //创建一个jquery构造函数
                function jQuery(selector){
                    return new jQuery.fn.init(selector); //返回一个jQuery对象,可以访问jQuery.fn.init.prototype与jQuery.prototype中属性
                }
              
               
                //添加一个init函数给jQuery.fn
                jQuery.fn=jQuery.prototype={
                    constructor:jQuery,
                    init:function(selector){  //通过init构造函数可以保持生产选取到dom节点的对象
                         if(selector==="undefined"){this.length=0;return this;}//未选择
                         if(selector.nodeType==1){this[0]=selector;}else{this[0]=document.getElementById(selector);} //这里this[0]指创建此jQuery实例对象的属性0,且访问格式只能是此jQuery对象[0]
                          this.length=1;  //给jQuery对象添加一个length属性
                    },
                    css:function(name,value){
                          this[0].style[name]=value;
                          return this;  //链式调用 ,这里this指css()的调用者--jquery的实例对象,而不是css构造出来的实例对象,返回jQuery对象
                    },
                    hide:function(){
                          var self=this;
                          setTimeout(function(){
                            self[0].style.display="none"; //self[0]为选取的Dom节点对象
                          },2000);
                        
                          return this; //链式调用,通过jQuery原型的实例对象获取
                    },
                    float:function(position){
                          this[0].style.float=position;
                          return this; //链式调用,返回此时调用的jQuery对象
                    }
    
                }
                //将jQuery原型赋给jQuery.fn.init的原型,让init可以生产jQuery的实例
                jQuery.fn.init.prototype=jQuery.prototype;
    

        我的注释写的可能有些乱,但作为学习的资料,我希望写的详细一点,通过我的注释和你的思考,我相信理解起来并不困难。

           需要说明的是,我这段代码只能实现对有id标签的元素的选取,并提供了改变位置和隐藏以及改变css样式的功能,下面用一段代码测试:

             <p id="qq">234</p>
             <script type="text/javascript">
              jQuery("qq").float("right").hide();
             </script>
    

      我这里,功能完全可以实现,不知道你的怎么样,如果有啥问题,你可以给我留言。

  • 相关阅读:
    环境变量学习(二)Mac 可设置环境变量的位置
    环境变量学习(一)简介、查看
    shell学习(二)安装shell环境
    npm学习(十八)npm scripts 使用指南
    nodemon学习(二)实战
    nodemon学习(一)简介、安装、配置、使用
    Error: listen EADDRINUSE 127.0.0.1:8888错误解决
    树莓派创建wifi热点
    JavaScript中的数据类型转换
    Packstack 搭建 OpenStack 报 MariaDB 错误的处理
  • 原文地址:https://www.cnblogs.com/zhu-xingyu/p/5272921.html
Copyright © 2011-2022 走看看