jquery使用有一段时间了,但是有一些api的实现实在想不通。小编参考相关资料源码,现在把我的学习过程和收获分享给大家。
下面将使用简化的代码来介绍,主要关注jquery的实现思想~>_
//匿名立即执行函数//.防止污染全局空间//.选择性保护内部变量(function(window, undefined){//第二参数undefined设置而不传的原因:// 外部发生这种情况:var undefined = 时,undefined会被篡改// 设置第二参数而不传,则undefined就会被重置回原来值function jquery(sel){return new jquery.prototype.init(sel);}jquery.prototype = {constructor: jquery,init: function(sel){if(typeof sel === 'string'){var that = this;//jquery内部使用的是sizzle,这里使用queryselectorall替代var nodelist = document.queryselectorall(sel);array.prototype.foreach.call(nodelist, function(val, i){that[i] = val;})this.selector = sel;this.length = nodelist.length;}}}jquery.prototype.init.prototype = jquery.prototype;//对外暴露jquery:将jquery绑定在window上面window.$ = jquery;})(window);
--------------------------
jquery一开始使用匿名立即执行函数包裹其内部,并在第5行对外暴露;
所谓的匿名立即执行函数即这个函数是匿名的(没有名字)、定义完后立即调用的;
当我们在外部调用$(div)时,其实调用的就是内部的jquery(div);
(function(window, undefined){//内部变量//对外暴露jquery:将jquery绑定在window上面window.$ = jquery;})(window);$(div)
--------------------------
好,接下来稍复杂点,下面的代码主要实现如图的互相引用:
以$('div')调用为例:
从第2行代码可以看出,jquery使用jquery.prototype.init来实例化jquery对象,但这会带来一个问题:
实例化的对象只能访问到init下的变量,而不能访问到jquery.prototype(jquery对外提供的api绑定在该对象下)。
于是乎,补写第21行代码,将init.prototype指向jquery.prototype即可。
这样就完成了,使用init来实例化,且可以在init作用域下访问到jquery.prototype。
function jquery(sel){return new jquery.prototype.init(sel);}jquery.prototype = {constructor: jquery,init: function(sel){if(typeof sel === 'string'){var that = this;//jquery内部使用的是sizzle,这里使用queryselectorall替代var nodelist = document.queryselectorall(sel);array.prototype.foreach.call(nodelist, function(val, i){that[i] = val;})this.selector = sel;this.length = nodelist.length;}}}jquery.prototype.init.prototype = jquery.prototype;
为什么使用jquery.prototype.init来实例化对象,而不直接使用jquery函数呢?
假设使用jquery函数来实例化对象,这样对象之间的引用的确可以简化为 jquery-->jquery.prototype。
但是调用会变得繁琐起来:new $('div'),所以基于这个考虑(猜测(⊙0⊙)),在内部使用较为复杂的实现,来简化调用。
--------------------------
好,最后,再来看一下init的实现。同样也简化了代码,只实现了最常用的一种情况。
jquery会把获取到的nodelist处理成数组(方便后续使用),并在其下挂载一些变量,如length,selector。
init: function(sel){if(typeof sel === 'string'){var that = this;//jquery内部使用的是sizzle,这里使用queryselectorall替代var nodelist = document.queryselectorall(sel);array.prototype.foreach.call(nodelist, function(val, i){that[i] = val;})this.selector = sel;this.length = nodelist.length;}}
本文所述到此结束,下篇文章将给大家介绍jquery链式调用与show知识浅析,欲了解更多资讯敬请关注脚本之家网站!
