jquery美元背后的一点小技巧

1、如
【菜科解读】
在Jquery中,$是JQuery的别名,所有使用$的地方也都可以使用JQuery来替换,如$('#msg')等同于JQuery('#msg') 的写法。
1、如何给一个id为casper的标签添加一个名为“world”的class
考虑下面一个场景,假设我们页面上有个id为casper的div标签,如下所示
casper是个大傻瓜,啦啦啦啦啦现在我们想要给它添加一个class,比如“world”,用jquery的话如何实现?很简单,不卖关子
$('#casper').addClass('world');很好,接下来我们思考:如何不用jquery,我们如何如何实现实现上述功能?最简单的方式:
var node = document.getElementById('casper');node.className += ' world';getElementById、getElementsByTagName神马的,名字老长老长的,写着有点不爽,于是把getElementById这个方法用美元($)包装下:
function $(id){ return document.getElementById(id);$('casper').className += ' world';className品字符串神马的,jquery的调用方式相比麻烦多了,那再改进下:
function $(id){
var node = document.getElementById(id); node.addClass = function(addName){ node.className += ' ' + addName; return document.getElementById(id);$('casper').addClass('world');看上去挺像那么一回事了,多优雅的接口啊(热泪盈眶中)~
真的是这样吗,再仔细瞧瞧?于是果断发现不对劲的地方:对于$,每次调用,都会给返回的dom元素上添加一个addClass方法,这对空间来说是极大的浪费。
当然,可以将addClass方法抽取出来:
function addClass(className){
//实现略function $(id){ var node = document.getElementById(id); node.addClass = addClass; return document.getElementById(id);$('casper').addClass('world');原先的空间浪费问题可以在很大程度上得到解决,但明显这解决方法还不够好。
如果有那么一种实现方式,让所有的对象实例都共享一个方法。
。
。
2、jQuery中的实现思路
同样不必卖关子,这里说的就是原型方法,我们再看下jquery的调用方式
$('#casper').addClass('world');$('#casper')并不是像我们上面那样,简单地将id为casper的元素返回。
实际上,$('#casper')返回的是一个jQuery对象,该对象特征如下:
拥有一个length属性,length等于你调用$选中的元素的数目,在$('#casper')中为1
拥有0~n-1的实例属性,分别对应调用$时选中的第1~第n个元素,如本例中$('#casper')[0]即为目标dom元素
拥有一堆原型方法,如常见的addClass、removeClass、bind等
根据上面三点,很容易对我们之前写的代码进行修改,如下:
function $(id){
this[0] = document.getElementById(id); this.length = 1;$.prototype.addClass = function(className){ this[0].className += ' ' + className;var noode = new $('casper');node.addClass('world');其实就几行代码的事情,但。
。
。
还是觉得有些不对劲,new $('casper'),平常在用jquery的时候似乎不需要new一下的说,想想看,我们代码中一坨new是多么可怕的事情~
好吧,其实是因为jQuery帮你完成了构造函数调用的这部分工作,这一小小的细节改善对jQuery的流行起到了很大的帮助。
按照这个思路,继续修改之前的代码:
function $(id){
if(!(this instanceof $) return new $(id); //加了这么个语句 this[0] = document.getElementById(id); this.length = 1;//其他一样,节省空间不贴代码在上面的代码中,只有一点小小的修改,就是加了个判断语句 if(!(this instanceof $)) ,作用在于判断,当$被调用时,究竟是采用以下两种调用方式的哪一种,关于这种判断方式,可参考之前写的《【经验总结】构造函数的强制调用》:
$('casper'),直接调用,于是this为window
new $('casper'),此时$为构造方法,this instanceof $ == true
3、jQuery中的源码实现以及问题所在(俺的疑惑)
罗嗦了这么多,我们看看关于这点,jQuery里是如何实现的,源码大致如下,一些不相干的代码略过:
(function( window, undefined ) {
//去掉无关变量声明等,防止干扰分析var jQuery = (function() { // Define a local copy of jQuery var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); //一堆无关细节暂时略过 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; return jQuery;})();window.jQuery = window.$ = jQuery;})( window );对于研究过jQuery源码或曾经打算研究jQuery源码的同学来说,上面这段代码肯定不会陌生,它有一个特点:看上去比较晦涩,特别是是结合了jQuery源码里面比较诡异的代码缩进~
通过闭包返回的jQuery对象,闭包里面是有jQuery函数定义,jQuery函数里面return了new jQuery.fn.init 。
。
。
快速看懂上面这段代码的秘诀在于:一个支持代码高亮和职能中括号匹配的编辑器,比如webstorm。
。
。
上面只是开个小玩笑,绕了这么久,无法是想做下面几件事情:
无论有没有new,只要调用$,都给你返回一个jQuery对象(实际上jQuery.fn.init才是实际的构造函数)
将jQuery.fn.init.fn指向jQuery.prototype,这样的话,当我们通过$.fn.newPrototypeAttr 方式向jQuery添加原型属性或方法,其实最终都成为了jQuery.fn.init地原型属性或方法
将constructor属性指向jQuery,不然$('#casper').constructor 获得的会是jQuery.fn.init
个人觉得上面这段代码有些费解,似乎完全可以采用相对不那么曲折的方式实现,如下所示,其实思路都是相同的:
然后,就是添加各种原型方法了,兼容性处理和优雅的API,这块才是精华,这里还没讲到。
(function(){
var jQuery = function(id){ return new _jquery(id); var _jquery = function(id){ //此处各种选择分支神马的都忽略~ this[0] = document.getElementById(id); this.length = 1; jQuery.fn = jQuery.prototype = { constructor: jQuery, addClass: function(className){ this[0].className += ' ' + className; _jquery.prototype = jQuery.fn; window.$ = window.jQuery = jQuery;})(); jquery,美元,背,后的,一点,小,技巧,在,Jquer吴破楚入郢之战何时爆发的?其历史背景是什么?
公元前506年,吴楚决战中,率领吴军大败楚军,攻入都城郢,逃到随国。
楚国向秦国求救,申包胥哭秦庭,感动。
秦国发兵救援楚国,帮助楚国收回都城复国。
撤后,楚军又被吴军连连击败,楚国不得不迁都以避吴军锋芒。
历史背景 春秋历经晋楚争霸(主要三次大战役有前632年晋胜、前597年楚胜、前575年晋胜;晋两胜一败;楚一胜两败,鄢陵之战时楚王被射瞎一只眼睛),弭兵之会(公元前546年)后,晋楚大体平分霸权,晋国总体上占优势。
晋国为了继续打击楚国,在楚国后背上插了一刀,扶助南方新兴的吴国来抗衡(比如派人教授吴人"车战步战"等陆战之法等,使用马匹、战车、弓箭及各种战术等)。
吴国、晋国皆为之国。
吴国开国之君"吴太伯"是周文王的伯父;晋国开国之君""是周武王与之子(邑姜为齐太公吕尚即之女,今山西太原晋祠因纪念唐叔虞及其母后邑姜而兴建),传说"桐叶封弟"。
周敬王十四年(前506年),有周王大臣参加的中原十八国诸侯会于召陵,准备攻楚。
因盟主晋国临时改变主张,未能实现。
原楚属国蔡、唐自愿助吴攻楚。
孙武等认为楚已完全孤立,实力亦大有削弱,吴遂与蔡、唐联合进攻,发动了"涉淮逾泗,越千里而战"的战略决战,吴楚之战决战开始后,吴军在柏举(今湖北麻城东北)击败楚军主力后,尾随追击,五战五胜,仅10天即攻入楚都郢城。
随机文章探寻唐代黑石号沉船宝藏,6万件古董价值4000万美金蚊式战斗机用的什么木材,专用巴尔沙木制造(速度碾压德军战机)一百维空间是什么样子,看任何事物只是一个点(纯猜想)最详细导弹常识大全,军事专家和爱好者必知的常识销售28法则是什么意思,8成的利润来自2成的客户
蔡国曾参加的两场战争,背后的真相让人心酸
它和神话人物杨戬并没有关系,真正与它相关的是春秋时期的一个小诸侯国,它的名字叫蔡国。
我第一次接触到它的名字,是在《》的管蔡世家中。
全部读完了这一章,我最大的感受就是觉得这个国家很是不幸。
虽然是一个小国,但是却一直起起落落,数次因为种种原因和大国发生争执,它的命运似乎一直在重复着被灭和复国的死循环,无药可解。
首先,我们一起来回顾一下它与郑国之间的战争。
公元前719年,卫国与郑国发生了一场战争,这场战争因为发生在郑国的东门地区,因此被后人称之为东门之战,蔡国作为参战国之一也出现在了这场战役里。
为什么蔡国要参加这场战役呢?原因很复杂,也很简单。
虽然当时正值春秋初年,蔡国还是一个百乘之国,能做到自保就可以了,没必要参加到像东门之战这样弊大于利的战役中来,但是出于种种原因,即便是蔡国和郑国之间没有怨仇,它也必须作为参战国出现。
第一,蔡国和卫国同属三监,和周天子之间有着亲族关系,一旦不参战的话,舆论上的压力就足够让蔡国失去外交上的威信,甚至给其他国家留下攻打的借口了。
所以为了避免落下不敬天子的名声,蔡国只能参战。
第二,从地理位置上讲,东门之战的发起国卫国和蔡国的地理位置更加接近,当时的卫国国君州吁一向刚愎自用、喜爱用兵,如果蔡国拒绝了卫国,州吁会不顾情面立刻攻打蔡国。
第三,东门之战看起来是卫国和郑国之间的战争,实际上却是周天子和郑国之间的一场较量,当时的郑国国君郑庄公是一位非常有野心的政治家,他的梦想是击败周王室,成为真正意义上的霸主。
而此时周王室的天子也是一心复兴周王室,所以自然不会甘心被欺压。
这场诸侯与天子间的较量必然会发起,所谓卫国和郑国之间的战争源头只是一根引线而已。
蔡国选择和小国们共同帮助周天子攻打郑国,如果胜利了会赢得一些荣誉。
可是选择避战或者帮助郑国攻打卫国,以郑庄公的野心,蔡国作为小国还是免不掉被郑国吞掉的命运。
既然争与不争结局都是一样的,那么还不如拼死一战。
出于这些理由,蔡国就这样成了参战国,准备参加一场恶战。
然而出乎蔡国意料的是,郑国竟然诈败了。
是因为担心寡不敌众,还是因为刚刚平定了共叔段发起的内乱,需要恢复国力呢? 这些原因都不是郑国诈败的原因,郑庄公之所以诈败,是因为出于一个政治家的敏锐嗅觉,他看透了他真正的敌人是谁。
根据史书记载,郑庄公在得知卫国联络了众小国企图攻打自己以后,只是非常平静地做出了这样一个决定,他先是将宋国的公子冯移居到了长葛,又造成了卫国战胜的名声让州吁回到了自己的国家。
郑庄公之所以能如此迅速果决地做出这两个决定,是因为他明白他和蔡国这样的小国之间并没有私仇,所以蔡国没有必战的理由,他的对手一直是周天子,是野心勃勃的宋国国君,是外强中干的之君州吁。
宋国国君不可怕,只要消除了导火索,他自然会失去和郑国交恶的理由。
州吁也不可怕,一旦他回了国,还有忠君之臣石碏替自己料理他。
既然已经诈败退敌,那么接下来郑庄公就要给真正的对手周天子进行一次有力地还击了。
公元前707年,周桓王再一次发起了对郑国的战争,只不过这次他再也没有迎来郑国诈败的结局,他等来的是一记来自郑庄公的重击。
周桓王失败了,参战的蔡国等小国也失败了。
周桓王不但被射中了肩膀,也被射掉了尊严,不久就去世了。
不过,蔡国等一众小国并没有被郑庄公报复,反而得到了援助,无不赞叹郑庄公的气度。
这场,使得郑国国力强盛,许多宿敌都向郑庄公伸出了橄榄枝。
当后来的周天子再想对付郑庄公时,这些小国已经彻底成了郑国的盟友了。
蔡国参与的这两场战争,论证了一个道理,那就是在尔虞我诈的乱世,对错只是借口,国君们真正在意的是得失。
一个小国,往往是无法决定自己的命运,它的结局从春秋初年就注定了沦为陪衬,或者就此消失。
随机文章这招太狠了!皇后到死都不知道 甄嬛为何要在景仁宫养鸽子清朝灭亡因太放水?八国联军开兵器库全部傻眼墨西哥干尸博物馆,世界最小婴儿干尸(刚出生)美军飞行员遇ufo曝光真相,大黄蜂战机追踪UFO失败两次风水宝地不葬无福之人,伤天害理命格差的人葬进去将引发横祸