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
一个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; }());
相关文章推荐
- QWrap简介之:Helper堆砌
- QWrap简介之:FunctionH 针对function的Helper
- QWrap简介之:HelperH 针对helper的Helper
- IP Helper API 简介(转)
- 企业程序库(六)——日志和规范应用程序块简介
- Ext.DomHelper.append简介
- Python数据库接口规范简介 -- DB-API
- IP Helper API 简介
- Servlet规范简介
- QWrap简介之:序
- QWrap简介之:retouch机制小结
- JavaScript AMD规范简介(一)
- QWrap简介之:Apps 应用--- 收获果实
- QWrap简介之:apps果实篇之:小结
- HTML4.01规范中英文对照-HTML4简介(1)
- J2EE的13个规范之(三) Servlet简介
- Servlet规范简介
- 《Java 本地接口规范》- 简介
- ISO 26262国际安全规范简介及其应用
- [组件技术]OSGi规范简介和实现