您的位置:首页 > 其它

QWrap简介之:Helper规范

2011-03-21 19:09 148 查看
Helper规范是一个很简单轻松的规范,这个在core/js/helper.h.js里有提到。
一个Helper是指同时满足如下条件的一个对象:
1。Helper是一个不带有可枚举proto属性的简单对象(这意味着你可以用for...in...枚举一个Helper中的所有属性和方法)
2。Helper可以拥有属性和方法,但Helper对方法的定义必须满足如下条件:
2.1. Helper的方法必须是静态方法,即内部不能使用this。
2.2. 同一个Helper中的方法的第一个参数必须是相同类型或相同泛型。

也可以分拆成三点来描述:
1。Helper是一个不带有可枚举proto属性的简单对象。 (纯洁)
2。Helper的所有方法必须是静态方法,即内部不能使用this。 (静态)
3。同一个Helper中的方法的第一个参数必须是相同类型或相同泛型。(针对性)

QWrap中,一个Helper对应的命名空间通常以“H”结尾,对应的js通常以“.h.js”结尾。
例如,QW.StringH是针对String的Helper的命名空间,它对应的js是“js/core/string.h.js”。
对于只满足“纯洁”“静态”特征的对象,也算是泛Helper,命名空间以“U”(util)结尾。
本来Util和Helper应该是继承关系,但是QWrap淡化了这些关系概念。

“纯洁”有什么用?----方便以后for in。----顺便说一下QWrap的一个脆弱:如果有人把Object的原型污染掉了,可能会产生一些隐患。----同学们啦,千万别污染Object的原型。
“静态”有什么用?----方便移植与函数变换。
“针对性”有什么用?----方便分组,以及移植与函数变换。

这里着重说一下“针对性”的意义。
1 方便分组: 针对字符串的很多方法,就放在StringH里,例如trim、byteLen、subByte、encode4Html、encode4Js;而针对Array的,则放在ArrayH里,如forEach、map、filter。
2 这些方法的第一个参数是它针对的变量。StringH里的所有方法的第一个参数都是字符串,而ArrayH里的所有方法的第一个参数都是数组或类数组(ArrayLike)。
3 有了这种针对性,我们就可以找标准(包括理论标准与事实标准)来实现堆砌代码了,例如StringH.contains(s,subStr) ArrayH.contains(arr, obj) NodeH.contains(parentEl,subEl)。同样是contains,它们各有标准、各得其所、互不冲突。
4 让批量转换有了理论依据。
当然,“纯洁”“静态”“针对性”,这三点对于批量转换都很重要。

好的,看几个Helper的实例,来感性的认识下Helper吧:
string.h.js (针对String的Helper)
View Code

/**
* @class FunctionH 核心对象Function的扩展
* @singleton
* @namespace QW
* @helper
*/
(function() {

var FunctionH = {
/**
* 函数包装器 methodize,对函数进行methodize化,使其的第一个参数为this,或this[attr]。
* @method methodize
* @static
* @param {function} func要方法化的函数
* @param {string} attr (Optional) 属性
* @return {function} 已方法化的函数
*/
methodize: function(func, attr) {
if (attr) {
return function() {
return func.apply(null, [this[attr]].concat([].slice.call(arguments)));
};
}
return function() {
return func.apply(null, [this].concat([].slice.call(arguments)));
};
},
/** 对函数进行集化,使其第一个参数可以是数组
* @method mul
* @static
* @param {function} func
* @param {bite} opt 操作配置项,缺省表示默认,
1 表示getFirst将只操作第一个元素,
2 表示joinLists,如果第一个参数是数组,将操作的结果扁平化返回
* @return {Object} 已集化的函数
*/
mul: function(func, opt) {
var getFirst = opt == 1,
joinLists = opt == 2;

if (getFirst) {
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);
}
};
}

return function() {
var list = arguments[0];
if (list instanceof Array) {
var moreArgs = [].slice.call(arguments, 0),
ret = [],
i = 0,
len = list.length,
r;
for (; i < len; i++) {
moreArgs[0] = list[i];
r = func.apply(this, moreArgs);
if (joinLists) {
if (r) {
ret = ret.concat(r);
}
} else {
ret.push(r);
}
}
return ret;
} else {
return func.apply(this, arguments);
}
};
},
/**
* 函数包装变换
* @method rwrap
* @static
* @param {func}
* @return {Function}
*/
rwrap: function(func, wrapper, idx) {
idx |= 0;
return function() {
var ret = func.apply(this, arguments);
if (idx >= 0) {
ret = arguments[idx];
}
return wrapper ? new wrapper(ret) : ret;
};
},
/**
* 绑定
* @method bind
* @via https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind * @compatibile ECMA-262, 5th (JavaScript 1.8.5)
* @static
* @param {func} 要绑定的函数
* @obj {object} this_obj
* @param {any} arg1 (Optional) 预先确定的参数
* @param {any} arg2 (Optional) 预先确定的参数
* @return {Function}
*/
bind: function(func, obj) {
var slice = [].slice,
args = slice.call(arguments, 2),
nop = function() {},
bound = function() {
return func.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments)));
};

nop.prototype = func.prototype;

bound.prototype = new nop();

return bound;
},
/**
* 懒惰执行某函数:一直到不得不执行的时候才执行。
* @method lazyApply
* @static
* @param {Function} fun  调用函数
* @param {Object} thisObj  相当于apply方法的thisObj参数
* @param {Array} argArray  相当于apply方法的argArray参数
* @param {int} ims  interval毫秒数,即window.setInterval的第二个参数.
* @param {Function} checker  定期运行的判断函数。<br/>
对于不同的返回值,得到不同的结果:<br/>
返回true或1,表示需要立即执行<br/>
返回-1,表示成功偷懒,不用再执行<br/>
返回其它值,表示暂时不执行<br/>
* @return {int}  返回interval的timerId
*/
lazyApply: function(fun, thisObj, argArray, ims, checker) {
checker = checker || function() {return true; };
var timer = function() {
var verdict = checker();
if (verdict == 1) {
fun.apply(thisObj, argArray || []);
}
if (verdict == 1 || verdict == -1) {
clearInterval(timerId);
}
},
timerId = setInterval(timer, ims);
return timerId;
}
};

QW.FunctionH = FunctionH;

}());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: