写在前面:本文比较基础,仅是一枚菜鸟接触jquery过程中的一点思考和总结,内容较基础,希望能对刚接触jQuery的童鞋有一点帮助 🙂
按照国际惯例(其实就是俺写作的习惯),首先抛出待问题的场景。至于问题的答案,文章并不会急着揭晓,而是通过逐层递进的方式,展现思考、解决一个问题的过程
1、如何给一个id为casper的标签添加一个名为“world”的class
考虑下面一个场景,假设我们页面上有个id为casper的div标签,如下所示
现在我们想要给它添加一个class,比如“world”,用jquery的话如何实现?很简单,不卖关子
很好,接下来我们思考:如何不用jquery,我们如何如何实现实现上述功能?最简单的方式:
getElementById、getElementsByTagName神马的,名字老长老长的,写着有点不爽,于是把getElementById这个方法用美元($)包装下:
className品字符串神马的,jquery的调用方式相比麻烦多了,那再改进下:
看上去挺像那么一回事了,多优雅的接口啊(热泪盈眶中)~
真的是这样吗,再仔细瞧瞧?于是果断发现不对劲的地方:对于$,每次调用,都会给返回的dom元素上添加一个addClass方法,这对空间来说是极大的浪费。当然,可以将addClass方法抽取出来:
原先的空间浪费问题可以在很大程度上得到解决,但明显这解决方法还不够好。如果有那么一种实现方式,让所有的对象实例都共享一个方法。。。
2、jQuery中的实现思路
同样不必卖关子,这里说的就是原型方法,我们再看下jquery的调用方式
$('#casper')并不是像我们上面那样,简单地将id为casper的元素返回。实际上,$('#casper')返回的是一个jQuery对象,该对象特征如下:
根据上面三点,很容易对我们之前写的代码进行修改,如下:
其实就几行代码的事情,但。。。还是觉得有些不对劲,new $('casper'),平常在用jquery的时候似乎不需要new一下的说,想想看,我们代码中一坨new是多么可怕的事情~
好吧,其实是因为jQuery帮你完成了构造函数调用的这部分工作,这一小小的细节改善对jQuery的流行起到了很大的帮助。按照这个思路,继续修改之前的代码:
在上面的代码中,只有一点小小的修改,就是加了个判断语句 if(!(this instanceof $)) ,作用在于判断,当$被调用时,究竟是采用以下两种调用方式的哪一种,关于这种判断方式,可参考之前写的《【经验总结】构造函数的强制调用》:
3、jQuery中的源码实现以及问题所在(俺的疑惑)
罗嗦了这么多,我们看看关于这点,jQuery里是如何实现的,源码大致如下,一些不相干的代码略过:
对于研究过jQuery源码或曾经打算研究jQuery源码的同学来说,上面这段代码肯定不会陌生,它有一个特点:看上去比较晦涩,特别是是结合了jQuery源码里面比较诡异的代码缩进~
通过闭包返回的jQuery对象,闭包里面是有jQuery函数定义,jQuery函数里面return了new jQuery.fn.init 。。。快速看懂上面这段代码的秘诀在于:一个支持代码高亮和职能中括号匹配的编辑器,比如webstorm。。。
上面只是开个小玩笑,绕了这么久,无法是想做下面几件事情:
个人觉得上面这段代码有些费解,似乎完全可以采用相对不那么曲折的方式实现,如下所示,其实思路都是相同的:
然后,就是添加各种原型方法了,兼容性处理和优雅的API,这块才是精华,这里还没讲到。
问题:jQuery源码的那种实现方式,至今不明白作用在哪?是有其他的考虑??知道的筒子往不吝赐教!
文中示例如有错漏,请指出;如觉得文章对您有用,可点击“推荐” 🙂
- 海报