yui3.0.0beta终于千呼万唤使出来,鼓掌!!!下载在这里:http://developer.yahoo.com/yui/3/
说到js的方法链式调用,的确,jquery确实给了wd们很多美好的回忆;所谓链式调用是一种语法上的小hack,也仅仅停留在代码级别,不过这种方法确实能使工程师用少量的代码达到复杂的操作目的,是一种很值得推广的技巧。不过yui2在这方面没作多少工作,yui3开始大量的使用这种技巧,让人猛然感觉语法风格和yui2的迥异。
在yui2中,我要对某个dom元素执行一系列的操作必须要这样:
var el = YAHOO.util.Dom.get(‘id’);
YAHOO.util.Dom.addClass(el,’className’);
YAHOO.util.Dom.setStyle(el,’display’,'block’);
在yui3中可以这样:
Y.get(‘#id’).addClass(‘className’).setStyle(‘display’,'block’);
语法上简洁了很多,这种写法就是所谓的链式调用。yui3的链式调用如何实现的、扩展行好不好呢?上篇介绍yui3的装饰者的时候涉及到一点这方面的内容:方法的声明+定义。比如,要对dom节点扩展一个fuck行为,则需要:
Y.mix(Y.DOM,{
fuck:function(o){
alert(o.innerHTML);//定义
}
});
Y.Node.addDOMMethods([
'fuck'//声明
]);
为什么不直接定义,而要加一个“声明“出来,这种做法是为了降低库模块之间的耦合,即我在定义这个fuck的时候不必知晓DOM内部的逻辑,DOM 在调用fuck的时候则会自动返回一个包装好的Node,这种做法增加了库的可扩展性。再来看一个例子,我要模拟一个‘人’的行为,分别用yui3和不用库来作,看两者的区别,基于yui3:
YUI().use(‘node’, function(Y){
Y.mix(Y.DOM,{
eat:function(o){
o.innerHTML += ‘吃!’;
},
drink:function(o){
o.innerHTML += ‘喝!’;
},
shit:function(o){
o.innerHTML += ‘拉!’;
},
pee:function(o){
o.innerHTML += ‘撒!’;
},
fuck:function(o){
o.innerHTML += ‘o!’;
}
});
Y.Node.addDOMMethods(['eat','drink','shit','pee','fuck']);
//runtime
Y.get(‘#aperson’).eat().drink().shit().pee().fuck();
});
“Y.get(’#aperson’).eat().drink().shit().pee().fuck()“这句即是这个person一溜烟的执行了吃喝拉撒干的动作,连隔都不带打的。
在来看看不用任何库作的方法链式调用:
var $ = function(id){
var _$ = function(id){
this.el = document.getElementById(id);
};
_$.prototype.eat = function(){
this.el.innerHTML+=’吃!’;
return this;
};
_$.prototype.drink= function(){
this.el.innerHTML+=’喝!’;
return this;
};
_$.prototype.shit = function(){
this.el.innerHTML+=’拉!’;
return this;
};
_$.prototype.pee = function(){
this.el.innerHTML+=’撒!’;
return this;
};
_$.prototype.fuck = function(){
this.el.innerHTML+=’o!’;
return this;
};
return new _$(id);
};
//runtime
$(‘aperson’).eat().drink().shit().pee().fuck();
这里的$(’aperson’).eat().drink().shit().pee().fuck()也是一溜烟的吃喝拉撒睡,但在实现具体方法的时候,每个方法都要return this,而真正灵活的扩展则不希望这样作。在js库流行的今天,这种降低耦合增加扩展性的小技巧显的尤为重要。