细说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>
我这里,功能完全可以实现,不知道你的怎么样,如果有啥问题,你可以给我留言。