mojs,一个javascript常用方法库,包含了浏览器中对storage、cookie的操作封装,e5 super,date日期处理,身份证、url中元素校验解析,及一些其他常用的方法集合(正则、extend、继承、类等...)。
源码采用AMD书写,以webpack打包,karma+jasmine单元测试,UMD格式输出。
一些底层的方法
var foo, obj1, obj2, obj3;
function Foo () {
this.a = 1
};
Foo.prototype.b = 2;
foo = new Foo();
obj1 = {
a: 1,
b: 2,
toString: 3,
isPrototypeOf: 4,
constructor: 5
};
obj2 = {
b: 22,
c: {
d: 6
}
};
obj3 = {
c: {
e: 7,
f: {
g: 8,
h: 9
}
}
};
hasc.has(obj, key)
判断是否是非继承属性
c.has(foo, 'a') => true c.has(foo, 'b') => false
forInc.forIn(obj, iteratee[, context])
兼容 IE8- 下有些不枚举的属性,例如'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
@param {object} obj
@param {function} iteratee
- param {..} value
- param {..} key
- param {object} forIn的第一个参数obj
@param {object} iteratee的上下文,可选
c.forIn(obj1, function(v, k) {
console.log(k + ':' + v)
})
=> 依次输出: 'a: 1', 'b: 2', 'toString: 3', 'isPrototypeOf: 4', 'constructor: 5'
extendc.extend([isDeep,] obj1, obj2, obj3...)
合并对象到第一个obj
@param {boolean} 是否深度复制,可选
@param {object|array} 目标对象
@params {object|array} 需要extend的对象,可多个参数
@return {object|array} extend后的object
c.extend(obj1, obj2) => {a: 1, b: 22, c: {d: 6}, toString: 3, isPrototypeOf: 4, constructor: 5}
// 浅拷贝
c.extend(obj2, obj3) => {b: 22, c: {e: 7, f: {g: 8, h: 9}}}
// 深度拷贝
c.extend(true, obj1, obj2, obj3)
=> {a: 1, b: 22, c: {d: 6, e: 7, f: {g: 8, h: 9}}, toString: 3, isPrototypeOf: 4, constructor: 5}
typec.type()
判断对象的类型
c.type({a: 1}) => 'object'
c.type('mojs') => 'string'
c.type(2) => 'number'
isBooleanc.isBoolean()
是否是Boolean类型
c.isBoolean({a: 1}) => false
isNumberc.isNumber()
是否是Number类型
isStringc.isString()
是否是String类型
isFunctionc.isFunction()
是否是Function类型
isDatec.isDate()
是否是Date类型
isRegExpc.isRegExp()
是否是RegExp类型
isObjectc.isObject()
是否是Object类型
isArrayc.isArray()
是否是数组
isArraylikec.isArraylike()
是否是类数组, 例如nodelist,arguments,具有length并且keys为0.1.2...的obj
c.isArraylike([1, 2, 3]) => true
c.isArraylike({1: 1, 2: 2, 3: 3, length: 3}) => true
c.isArraylike({1: 1, 2: 2, 3: 3}) => false
isNaNc.isNaN()
判断是否为NaN
c.isNaN(NaN) => true c.isNaN(undefined) => false
sizec.size(obj)
返回obj的长度
c.size([1, 2, 3]) => 3
c.size({a: 1, b: 2}) => 2
trimc.trim(text)
去掉字符串前后的空
c.trim(' abc defg ') => 'abc defg'
keysc.keys(obj)
获取对象的key集合
c.keys({a: 1, b: 2}) => ['a', 'b']
nowc.now()
当前时间戳
logc.log()
同console.log()
baseCreatec.baseCreate(prototype)
同Object.create(prototype)
@param {object} prototype
@return {object} 原型为参数prototype的对象
c.baseCreate() => {}
c.baseCreate({ a: Foo }).a => Foo
baseClassc.baseClass(subCtor, prototypes, superCtor)
创建一个构造函数(继承、原型方法都可选,继承可以通过新构造函数的superCtor访问父级构造函数)
@param {function} (子级)构造函数
@param {object} 原型的方法集,可选
@param {function} 父级构造函数,可选
@return {function} 新的构造函数
c.baseClass(A, {a: function() {}, b: function(){}}, B) => A继承B,并且prototype上添加方法a和b
c.baseClass(A, {a: function() {}, b: function(){}}) => A的prototype上添加方法a和b
c.baseClass(A, B) => A继承B
操作cookie的方法
Cookienew Cookie(options)
构造函数
@param {object} options
- isRaw {boolean} 是否原生字符(不转码), 默认为false
- isJson {boolean} 是否str->json, 默认为false
var
cookie = new Cookie(),
cookie2 = new Cookie({isRaw: true, isJson: true});
setcookie.set(name, value[, options])
设置cookie
@param {string} name
@param {..} value
@param {obj} options
- expires {number|string} 失效时长,单位 ‘天’, 默认为Session
- path {string} 路径,path只能设置当前path的子path, 默认为当前path
- domain {string} 域,domain只能设置当前domain的子domain, 默认为当前domain
- secure {boolean} 安全策略,只有https下能设置 ture or false, 默认为false
cookie.set('user', 'mo');
cookie2.set('user2', {a: 'mojs', b: 'modoc'}, {expires: 1});
getcookie.get(name)
读取cookie
@param {string} cookie的name
@return {..} cookie的value
cookie.get('user') => 'mo'
cookie2.get('user2') => {a: 'mojs', b: 'modoc'}
removecookie.remove(name)
删除cookie
@param {string} cookie的name
cookie.remove('user')
日期格式化、计算
var
birthday = new Date(), // 默认值,当前客户端时间Date实例
birthday2 = '/Date(562941040500+0800)/', // 非JS格式的时间戳,例如.NET
birthday3 = '1987/11/03 20:30:40', // 需要重新格式化的字符串,注意12小时制不支持
birthday4 = '1987/11/03', // 需要重新格式化的字符串
birthday5 = 562941040500, // 时间戳(number/string)
birthday6 = new Date('1987', '10', '03', '20', '30', '40', '500'); // Date实例
formatdate.format([date,] format)
格式化日期
@param {number/string/date} 需要格式化的date
@param {string} token字符串
@return {string} 格式化后的字符串
date.format(birthday6, 'YYYY-MM-DD HH:mm:ss:SSS') => '1987-11-03 20:30:40:500' date.format(birthday6, 'YY年M月D日 h时m分s秒 S毫秒 ddd') => '87年11月3日 8时30分40秒 500毫秒 周二' date.format(birthday6, '\\Q\\ww\\a,第Q季度,第ww周季度,A') => 'Qwwa,第4季度,第45周季度,PM'
token映射表 参照 http://momentjs.com/docs/#/displaying/,只引用了其中一部分,涉及到中文的部分稍微有调整
==================================================================
Token Output
Month M 1 2 ... 11 12
MM 01 02 ... 11 12
Quarter Q 1 2 3 4
Day of Month D 1 2 ... 30 31
DD 01 02 ... 30 31
Day of Year DDD 1 2 ... 364 365
DDDD 001 002 ... 364 365
Day of Week d 0 1 ... 5 6
ddd 周日 周一 ... 周五 周六
dddd 星期日 星期一 ... 星期五 星晴六
Week of Year w 1 2 ... 52 53
ww 01 02 ... 52 53
Year YY 70 71 ... 29 30
YYYY 1970 1971 ... 2029 2030
AM/PM A AM PM
a am pm
aa 上午 下午
Hour H 0 1 ... 22 23
HH 00 01 ... 22 23
h 1 2 ... 11 12
hh 01 02 ... 11 12
Minute m 0 1 ... 58 59
mm 00 01 ... 58 59
Second s 0 1 ... 58 59
ss 00 01 ... 58 59
Fractional Second S 0 1 ... 8 9
SS 0 1 ... 98 99
SSS 0 1 ... 998 999
==================================================================
add/subdate.add([date,] name, number)/date.sub([date,] name, number)
日期加减计算
@param {number|string|date} 需要格式化的date,不传默认为当前时间
@param {string} 单位['FullYear', 'Month', 'Date', 'Hours', 'Minutes', 'Seconds', 'Milliseconds', 'Time']
@param {number} n单位
@return {Date} 计算后的结果
date.add(birthday6, 'Hours', 1) => Tue Nov 03 1987 21:30:40 GMT+0800 (CST) date.sub(birthday6, 'Minutes', 1) => Tue Nov 03 1987 20:29:40 GMT+0800 (CST)
es5 super 其中each,map,filter,some,every可以应用到类数组,对象 indexOf,lastIndexOf,reduce,reduceRight可以应用到类数组
eaches5.each(obj, iteratee[, context])
遍历类数组或者对象,如果想终止循环return false即可
@param {arraylike|object} 类数组或者对象
@param {function} 迭代函数
- param {..} value
- param {..} index|key
- param {array|object} each的第一个参数
@param {object} iteratee的上下文,可选
mapes5.map(obj, iteratee[, context])
遍历类数组或者对象,返回一个新数组(obj执行iteratee后的返回值的集合)
@param {arraylike|object} 类数组或者对象
@param {function} 迭代函数
- param {..} value
- param {..} index/key
- param {array|object} map的第一个参数
@param {object} iteratee的上下文,可选
@return {array} 结果
filter
遍历类数组或者对象,返回一个新数组(obj执行iteratee后返回值为真的value的元素的集合),其他同map
some
遍历类数组或者对象,obj执行iteratee后返回值如果有一个为真,则返回true,否则返回false,其他同map
every
遍历类数组或者对象,obj执行iteratee后返回值如果全为真,则返回true,否则返回false,其他同map
indexOfes5.indexOf(array, item[, from])
返回item在arraylike中的索引值(从0开始找),如果item不存在arraylike中就返回-1,原生不支持NaN
@param {arraylike} 需要查找的类数组
@param {..} 需要查找的元素
@param {number} 开始索引,可选
@return {number} 查找到元素的索引值
lastIndexOf
同indexOf,区别是从arraylike的末尾开始(从右到左)
bindes5.bind(func, context[, arg1] [, arg2...])
函数绑定
@param {function} 需要绑定上下文或者是添加参数的函数
@param {object} func的上下文
@params {..} 需要添加的n个参数
@return {function} 绑定上下文或者是添加参数后函数
reducees5.reduce(arraylike, iteratee[, memo][, context])
接收一个函数作为累加器,类数组中的每个值从左到右开始缩减,最终为一个值
@param {arraylike} 类数组
@param {function} 迭代函数
- param {..} previousValue
- param {..} currentValue
- param {..} index/key
- param {array|object} reduce的第一个参数
@param {..} 可选,作为第一次调用iteratee的第一个参数,如果不存在,则把第一次要iteratee的value复制给memo,并且跳过index这次iteratee
@param {object} iteratee的上下文,可选
reduceRight
同reduce,区别是从类数组的末尾开始(从右到左)
身份证的校验以及从从身份证号码中获取一些信息,例如出生日期,性别
身份证规则 ===================================================================== 身份证15位编码规则 -- dddddd yymmdd xx p dddddd : 地区码 yymmdd : 出生年月日 xx : 顺序类编码,无法确定 p : 性别,奇数为男,偶数为女 身份证18位编码规则 -- dddddd yyyymmdd xxx y dddddd : 地区码 yyyymmdd : 出生年月日 xxx : 顺序类编码,无法确定,奇数为男,偶数为女 y : 校验码,该位数值可通过前17位计算获得 18位号码加权因子为 : WI = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1] 校验位集合 : CODE = [1, 0, 'x', 9, 8, 7, 6, 5, 4, 3, 2] 校验位index计算公式 : index = mod(∑(ai×Wi), 11) =====================================================================
IdCardnew IdCard(num)
构造函数
@param {string} 身份证号,这里必须是string格式,因为身份证号超出了js的整数精度范围
var idCard = new IdCard('610125198711037137');
checkCode
验证校验位,针对18位
@return {boolean}
idCard.checkCode() => true
checkBirth
验证出生日期
@return {boolean}
idCard.checkBirth() => true
getBirth
获取出生日期
@return {object} 返回对象
- year {number}
- month {number}
- day {number}
idCard.getBirth() => {year: '1987', month: '11', day: '03'}
getSex
获取性别
@return {string}
idCard.getSex() => '男'
读取或设置object path下的value
var obj = { f: { g: 'blog' } };
setobjectPath.set(obj, path, value)
设置object path下的value
@param {object} obj
@param {string} path
@param {..} value
@return {boolean} 成功true,失败false
objectPath.set(obj, 'a.d', 'mojs') => obj.a.d = 'mojs' objectPath.set(obj, 'a.b.e', 'modoc') => obj.a.b.e = 'modoc'
getobjectPath.set(obj, path)
读取object path下的value
@param {object} obj
@param {string} path
@return {..} value
objectPath.get(obj, 'f.g') => 'blog' objectPath.get(obj, 'a.b.e') => 'mojs'
解析url
url注解
=====================================================================
http://username:password@www.example.com:80/path/file.name?query=string#anchor
|__| |______| |______| |_____________||_||___||________||___________||_____|
| | | | | | | | |
protocol user password host port directory file query anchor
|_______________| |_____________|
| |
userInfo path
|___________________________________||_________________________________|
| |
authority relative
|___________________________________________________________________________|
|
source
=====================================================================
ParseUrlnew ParseUrl(url)
构造函数
@param {string} 默认为location.href
var parseUrl = new ParseUrl('http://username:password@www.example.com:80/path/file.name?query=string#anchor');
getAttrparseUrl.getAttr([name])
读取url中的attr,name为空,则返回所有attr
@param {string} name,可选 范围"source", "protocol", "authority", "userInfo", "user",
"password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"
@return {string} value
parseUrl.getAttr('port') => '80'
url.getAttr('protocol') => 'http'
getParamparseUrl.getParam([name])
读取url中的param,name为空,则返回所有param
@param {string} name
@return {string} value
parseUrl.getParam() => {query: 'string'}
parseUrl.getParam('query') => 'string'
pub/sub 发布订阅
var
data = [{
name: '熊大',
job: '阻止光头强砍树'
}, {
name: '熊二',
job: '调戏光头强'
}, {
name: '光头强',
job: '伐木'
}],
handler = handler = function(data) {
console.log(data.name + '应该' + data.job);
},
handler2 = function(data) {
console.log(data.name + '喜欢' + data.job);
};
publishpubSub.publish(message, data)
发布
@param {string} 消息,支持子message. eg. 'a.b.c'
@param {..} 执行订阅的handler时传入的data
subscribepubSub.subscribe(message, handler[, context])
订阅(注意,message不要包含'id_', eg. '...id_...')
@param {string} 消息
@param {function} 处理句柄
@param {object} handler执行的上下文,可选
pubSub.subscribe('a', handler);
pubSub.subscribe('a', handler2);
pubSub.publish('a', data[0]);
=> '熊大应该阻止光头强砍树'
=> '熊大喜欢阻止光头强砍树'
pubSub.subscribe('b', handler);
pubSub.subscribe('b.b', handler2);
pubSub.publish('b', data[1]);
=> '熊二应该调戏光头强'
=> '熊二喜欢调戏光头强'
pubSub.subscribe('c', handler);
pubSub.publish('c', data[2]);
=> '光头强应该伐木'
unsubscribepubSub.unsubscribe(message, handler)
取消订阅(只能取消此message上的handler,不能作用于子message)
@param {string} 消息
@param {function} 处理句柄,可选,如果为空则清除message上的所有handler
pubSub.unsubscribe('a', handler2);
pubSub.publish('a', data[0]);
=> '熊大应该阻止光头强砍树'
pubSub.unsubscribe('b');
pubSub.publish('b', data[1]);
=> '熊二喜欢调戏光头强'
clearpubSub.unsubscribe(message)
清除某个message(包含子message)或者所有message的订阅
@param {string} 消息,可选,如果message为空,则清除所有message.
pubSub.clear('b');
pubSub.publish('b', data[1]);
pubSub.clear();
pubSub.publish('c', data[2]);
常用的正则校验规则
// 校验,返回值为true/false
rules.isRequired('校验文本') // 必填
rules.isChinese(..) // 中文
rules.isDoubleByte(..) // 双字节
rules.isZipcode(..) // 邮政编码
rules.isQq(..) // QQ
rules.isPicture(..) // 图片
rules.isRar(..) // 压缩文件
rules.isMobile(..) // 手机号
rules.isMoney(..) // 金额(不能包含分隔符)
rules.isEnglish(..) // 英文字母
rules.isLowerCase(..) // 英文小写
rules.isUpperCase(..) // 英文大写
rules.isNumber(..) // 纯数字
rules.isInteger(..) // 整数
rules.isFloat(..) // 浮点数
rules.isRealName(..) // 姓名(中英文)
rules.isEmail(..) // 邮箱
rules.isUrl(..) // 网址 http://mhbsesal.com
rules.isIdCard(..) // 身份证
rules.isPhone(..) // 座机(区号-主号-分机号)029-8784326-11316
rules.isAreaNum(..) // 座机-区号
rules.isHostNum(..) // 座机-主号
rules.isExtensionNum(..) // 座机-分机号
rules.isIp(..) // IP地址
store的抽象类,针对storage中的key,一般不使用该类,常用他的子类LocalStore(options.storage = window.localStorage)、SessionStore(options.storage = window.sessionStorage)
AbstractStorenew AbstractStore(options)
构造函数
@param {object} options
- proxy {AbstractStorage} AbstractStorage实例
- key {string} key
- lifetime {string} 生命周期,默认'1H' 单位D,H,M,S. eg. '24H'
- rollbackEnabled {boolean} 是否回滚
var store = new AbstractStore({
proxy: new AbstractStorage({
storage: window.localStorage
})
key: 'USER'
}))
setstore.set(value[, tag][, isOld])
设置this.key下的value
@param {..} value
@param {string} 可选,tag标识,如果传递tag,get时会比较tag标识,不一致返回null
@param {string} 可选,默认false,是否设置回滚数据
@return {boolean} 成功true,失败false
setAttrstore.setAttr(name, value[, tag][, isOld])
设置this.key下的value中name的value
@param {String} name 支持通过路径的方式,如'a.b.c'
@param {..} value
@param {string} 可选,tag标识,如果传递tag,get时会比较tag标识,不一致返回null
@param {string} 可选,默认false,是否设置回滚数据
@return {boolean} 成功true,失败false
getstore.get([tag][, isOld])
读取this.key下的value
@param {string} 可选,tag标识,如果传递tag,get时会比较tag标识,不一致返回null
@param {string} 可选,默认false,是否设置回滚数据
@return {..} value
getAttrstore.getAttr(name[, tag][, isOld])
读取this.key下的value中name的value
@param {String} name 支持通过路径的方式,如'a.b.c'
@param {string} 可选,tag标识,如果传递tag,get时会比较tag标识,不一致返回null
@param {string} 可选,默认false,是否设置回滚数据
@return {..} value
getTagstore.getTag()
获取tag
removestore.remove()
移除存储对象
setExpireTimestore.setExpireTime()
设置失效时间
@param {number} timeout
getExpireTimestore.getExpireTime()
返回失效时间
rollbackstore.rollback([isClearOld])
回滚至上个版本
@param {string} 可选,默认false,回滚后是否清除回滚数据
@return {boolean} 成功true,失败false
AbstractStore的子类
var store = new AbstractStore({
key: 'USER'
})
AbstractStore的子类
var store = new AbstractStore({
key: 'USER'
})
工具方法集
guidutil.guid()
生成guid
@return {string} guid
util.guid() => 'd42fb5af-9b78-6320-9a79-327cb00ea561'
getByteInfoutil.getByteInfo(str[, index])
字符串的长度和index计算
@param {string} 要计算的字符串
@param {number} 可选,字符串(双字节长度为2)的index
@return {object} 返回对象
- length {number} 字符串(双字节长度为2)的长度
- index {number} 字符串的index,如果参数index为空,则该字段无返回值
util.getByteInfo('我的生日是1987年11月03日', 5) => Object {length: 24, index: 2}
util.getByteInfo('生日:1987-08-05') => Object {length: 16}
padutil.pad(str, len[, fill][, right])
字符串填充
@param {string} 需要处理的字符串,非字符串会先转换为字符串
@param {number} 填充的长度,如果需要处理的字符串大于此参数,则放弃
@param {string} 可选,填充字符,非字符串会先转换为字符串,默认为空格字符
@param {boolean} 可选,左边还是右边,默认为false,左边
@param {boolean} 可选,字符串的长度超过参数len是否截取,默认为false
@return {string} 处理后的字符串
util.pad('mo', 4, '-') => '--mo'
util.pad(19871103, 14, 0, true) => '19871103000000'
util.pad(19871103, 6, null, false, true) => '871103'