深层集化------QWrap的FunctionH.mul变换 之二

前一篇随笔讲过mul函数对get first、set all策略的应用,参见:http://www.cnblogs.com/jkisjk/archive/2011/01/13/QWrap_Function_mul_01.html
在该篇文章里,为了重点突出,略掉了mul的recursive参数。
recursive参数是一个boolean值,表示是否是深层集化。
QWrap的FunctionH.mul的完整代码如下:

代码
/** 对函数进行集化,使其第一个参数可以是数组
* @method mul
* @static
* @param {function} func
* @param {boolean} recursive 是否递归
* @param {boolean} getFirst 是否只是getFirst
* @return {Object} 已集化的函数
*/
FunctionH.mul
= function(func, recursive,getFirst){
//get First
if(getFirst){
if(recursive){
//以下代码,递归回溯寻找第一个有效元素,例如[[[],[]],[[],[el]]] 会找到el,再去执行func
//注意:诸如[null]、[undefined]这种会被当做非有效元素而忽略
function findFirst(list){
if(!(list instanceof Array)) {
return list;
}
for(var i=0;i<list.length;i++){
var firstOne = findFirst(list[i]);
if(null != firstOne) return firstOne;
}
};

return function(){
var firstOne = findFirst(arguments[0]);
if(firstOne){
var args = [].slice.call(arguments,0);
args[
0] = firstOne;
return func.apply(this,args);
}
};
}
return function(){
var list = arguments[0];
if(!(list instanceof Array)) return func.apply(this,arguments);
if(list.length) {
var args=[].slice.call(arguments,0);
args[
0]=list[0];
return func.apply(this,args);
}
}
}

//get All
var fn, newFunc = function(){
var list = arguments[0];
if(list instanceof Array){
var ret = [];
var moreArgs = [].slice.call(arguments,0);
for(var i = 0, len = list.length; i < len; i++){
moreArgs[
0]=list[i];
var r = fn.apply(this, moreArgs);
ret.push(r);
}
return ret;
}
else{
return func.apply(this, arguments);
}
}
fn
= recursive ? newFunc : func;

return newFunc;
};


例如:
function setValue(el, value){
    el.value=value;
};

var setValue2=mul(setValue,false);
它可以这样调用:
setValue2(el1,'hello');
setValue2([el1,el2],'hello');

可是,它不能这样用:
setValue2([ [el1,el2], [el3,el4], [[el9,el9]] ],'hello');
因为参数是多重数组,而setValue2只经过浅层集化,所以不能处理深层数组。

对于需要处理深层数组的函数,可以进行深层集化。
如:
var setValue3 = mul(setValue,true);

深层数组在现实中会用到吗?
会的。
看以下这句话:
W(‘#id’).show().query(‘>*’).show().query(‘>*’).setStyle(‘color’,’red’);
//show #id ; 再show其儿子 ; 再为其孙子设color
W(‘#id’)的结果是 W([el]);
W(‘#id’).show().query(‘>*’)的结果是 W([[subEl1,subEl2]])
W(‘#id’).show().query(‘>*’).show().query(‘>*’)的结果是W([ [ [subEl1_1,subEl1_2], [subEl2_1,subEl2_2] ] ]);
也就是,被包装的是一个深层数组,而不是一个一维数组。
这就要求:W.prototype.css方法,能够处理深层数组。
是的,setStyle方法是由 以下方法经过深层集化后得到的。
NodeH.setStyle=function(el,prop,value){

  el.style[prop]=value;

}


1. 对于setter来说,深层集化,就是一层一层的调用。

2. 对于queryer来说,深层集化,就是一层一层的调用,并将结果返回。queryer可能会导致数组层数变深,
例如以下queryer:
W.prototype.query(selector)
W.prototype.getElementsByClassName(className).
部分queryer保持同样的数组深度,例如以下queryer:
W.prototype.nextSibling(selector)
W.prototype.previousSibling(selector).
W.prototype.ancestorNode(selector).

3. 对于getter来说,如果采用getFirst策略,则需要在深存数组中找到第一个有效的元素,进行getter.
例如,getValue([[],[],[[],[el1,el2]]]) ,它应该返回的是el1.value。

注:
QWrap的NodeW的方法,都是经过深层集化的。

附:
QWrap 参见:http://github.com/wedteam/qwrap



posted on 2011-01-13 17:57  JKisJK  阅读(863)  评论(1编辑  收藏  举报

导航