diff --git a/.gitignore b/.gitignore index 4196d7e..11df8b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +.history node_modules /dist package-lock.json diff --git a/docs/index.html b/docs/index.html index 6e68572..e1de5dc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -13,4 +13,4 @@ var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); } - })();
\ No newline at end of file + })();
\ No newline at end of file diff --git a/docs/static/css/app.e1992a6b.css b/docs/static/css/app.10e8b0b2.css similarity index 94% rename from docs/static/css/app.e1992a6b.css rename to docs/static/css/app.10e8b0b2.css index 588a729..c3699c6 100644 --- a/docs/static/css/app.e1992a6b.css +++ b/docs/static/css/app.10e8b0b2.css @@ -1 +1 @@ -#app,body,html{height:100%}body,html{min-width:1200px;margin:0;padding:0;color:#000;font-size:14px;overflow:hidden;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,\\5FAE\8F6F\96C5\9ED1,Arial,sans-serif}body *,html *{box-sizing:border-box}body ul,html ul{list-style:none;margin:0;padding:0}body .link,html .link{color:#409eff;text-decoration:none}body p,html p{margin:14px 0;font-size:14px}.keyword-lighten{color:#000;background-color:#ff0}.page-container{height:100%;margin:0 auto;overflow:hidden}.page-container .aside{position:fixed;top:0;left:0;width:240px;height:100%;flex-shrink:0;overflow:auto;float:left;border-right:1px solid #dcdfe6;padding:100px 0 30px 0}.page-container .aside .header{position:fixed;top:0;left:0;text-align:center;width:220px;background-color:#fff}.page-container .aside .header .title{font-size:28px;margin:10px 0 0 0;text-align:center}.page-container .aside .header .title a{color:#409eff;text-decoration:none;cursor:pointer}.page-container .aside .header .search-wrapper{padding:10px 0}.page-container .aside .header .search-wrapper .search-input{width:60%;min-width:120px;max-width:200px;height:26px;border:1px solid #dcdfe6;border-radius:4px;padding-left:10px}.page-container .aside .menu-item{padding-left:15px}.page-container .aside .menu-item.active{border-right:4px solid red}.page-container .aside .menu-item .menu-link{line-height:30px;font-weight:700;font-size:16px;cursor:pointer}.page-container .aside .menu-item .child-menu .menu-link{line-height:22px;font-size:14px;font-weight:inherit}.page-container .aside .menu-item .child-menu .menu-link:hover{text-decoration:underline}.page-container .body{width:100%;height:100%;overflow:auto;float:left;padding:0 10px 0 280px}.page-container .body .api-item .title{font-weight:700;font-size:16px}.page-container .body .api-item .param-table{border-collapse:collapse;border-spacing:0;width:600px;text-align:center;border-left:1px solid #dcdfe6;border-top:1px solid #dcdfe6}.page-container .body .api-item .param-table tr:first-child,.page-container .body .api-item .param-table tr:hover{background-color:#f6f8fa}.page-container .body .api-item .param-table td{padding:4px;border-right:1px solid #dcdfe6;border-bottom:1px solid #dcdfe6}.is-donation[data-v-708e691e]{font-size:15px;font-weight:700;color:green}.donation-item[data-v-708e691e]{padding:20px 0 600px 0;text-align:center} \ No newline at end of file +#app,body,html{height:100%}body,html{min-width:1200px;margin:0;padding:0;color:#000;font-size:14px;overflow:hidden;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,\\5FAE\8F6F\96C5\9ED1,Arial,sans-serif}body *,html *{box-sizing:border-box}body ul,html ul{list-style:none;margin:0;padding:0}body .link,html .link{color:#409eff;text-decoration:none}body p,html p{margin:14px 0;font-size:14px}.keyword-lighten{color:#000;background-color:#ff0}.page-container{height:100%;margin:0 auto;overflow:hidden}.page-container .aside{position:fixed;top:0;left:0;width:240px;height:100%;flex-shrink:0;overflow:auto;float:left;border-right:1px solid #dcdfe6;padding:100px 0 30px 0}.page-container .aside .header{position:fixed;top:0;left:0;text-align:center;width:220px;background-color:#fff}.page-container .aside .header .title{font-size:28px;margin:10px 0 0 0;text-align:center}.page-container .aside .header .title a{color:#409eff;text-decoration:none;cursor:pointer}.page-container .aside .header .search-wrapper{padding:10px 0}.page-container .aside .header .search-wrapper .search-input{width:60%;min-width:120px;max-width:200px;height:26px;border:1px solid #dcdfe6;border-radius:4px;padding-left:10px}.page-container .aside .menu-item{padding-left:15px}.page-container .aside .menu-item.active{border-right:4px solid red}.page-container .aside .menu-item .menu-link{line-height:30px;font-weight:700;font-size:16px;cursor:pointer}.page-container .aside .menu-item .child-menu .menu-link{line-height:22px;font-size:14px;font-weight:inherit}.page-container .aside .menu-item .child-menu .menu-link:hover{text-decoration:underline}.page-container .body{width:100%;height:100%;overflow:auto;float:left;padding:0 10px 0 280px}.page-container .body .api-item .title{font-weight:700;font-size:16px}.page-container .body .api-item .param-table{border-collapse:collapse;border-spacing:0;width:600px;text-align:center;border-left:1px solid #dcdfe6;border-top:1px solid #dcdfe6}.page-container .body .api-item .param-table tr:first-child,.page-container .body .api-item .param-table tr:hover{background-color:#f6f8fa}.page-container .body .api-item .param-table td{padding:4px;border-right:1px solid #dcdfe6;border-bottom:1px solid #dcdfe6}.is-donation[data-v-07f405e2]{font-size:15px;font-weight:700;color:green}.donation-item[data-v-07f405e2]{padding:20px 0 600px 0;text-align:center} \ No newline at end of file diff --git a/docs/static/js/app.e597c307.js b/docs/static/js/app.9b08825e.js similarity index 69% rename from docs/static/js/app.e597c307.js rename to docs/static/js/app.9b08825e.js index a67e6ae..7e991d5 100644 --- a/docs/static/js/app.e597c307.js +++ b/docs/static/js/app.9b08825e.js @@ -1 +1 @@ -(function(e){function n(n){for(var a,l,r=n[0],d=n[1],c=n[2],m=0,u=[];m true\n XEUtils.isDate(new Date()) // true\n "]},{name:"isValidDate",args:"val",title:"和 isDate 的区别是同时判断类型与有效日期,如果为无效日期 Invalid Date 则返回 false",desc:"",params:[],codes:["\n XEUtils.isValidDate('2017-12-20') // false\n XEUtils.isValidDate(1514096716800) // false\n XEUtils.isValidDate(new Date('abc')) // Invalid Date => false\n XEUtils.isValidDate(new Date()) // true\n "]},{name:"isError",args:"val",title:"判断是否 Error 对象",desc:"",params:[],codes:["\n XEUtils.isError(null) // false\n XEUtils.isError({}) // false\n XEUtils.isError(new TypeError('error')) // true\n XEUtils.isError(new Error('error')) // true\n "]},{name:"isTypeError",args:"val",title:"判断是否 TypeError 对象",desc:"",params:[],codes:["\n XEUtils.isTypeError(null) // false\n XEUtils.isTypeError({}) // false\n XEUtils.isTypeError(new Error('error')) // false\n XEUtils.isTypeError(new TypeError('error')) // true\n "]},{name:"isEmpty",args:"val",title:"判断是否为空对象",desc:"",params:[],codes:["\n XEUtils.isEmpty([11, 22]) // false\n XEUtils.isEmpty({a:null}) // false\n XEUtils.isEmpty(null) // true\n XEUtils.isEmpty({}) // true\n XEUtils.isEmpty([]) // true\n "]},{name:"isNull",args:"val",title:"判断是否为 Null",desc:"",params:[],codes:["\n XEUtils.isNull(0) // false\n XEUtils.isNull('') // false\n XEUtils.isNull(null) // true\n "]},{name:"isSymbol",args:"val",title:"判断是否 Symbol 对象",desc:"",params:[],codes:["\n XEUtils.isSymbol('a') // false\n XEUtils.isSymbol(Symbol('a')) // true\n "]},{name:"isArguments",args:"val",title:"判断是否 Arguments 对象",desc:"",params:[],codes:["\n XEUtils.isArguments([]) // false\n XEUtils.isArguments(arguments) // true\n "]},{name:"isElement",args:"val",title:"判断是否 Element 对象",desc:"",params:[],codes:["\n XEUtils.isElement({}) // false\n XEUtils.isElement(document.createElement('div')) // true\n "]},{name:"isDocument",args:"val",title:"判断是否 Document 对象",desc:"",params:[],codes:["\n XEUtils.isDocument({}) // false\n XEUtils.isDocument(document.createElement('div')) // false\n XEUtils.isDocument(document) // true\n "]},{name:"isWindow",args:"val",title:"判断是否 Window 对象",desc:"",params:[],codes:["\n XEUtils.isWindow({}) // false\n XEUtils.isWindow(document) // false\n XEUtils.isWindow(window) // true\n "]},{name:"isFormData",args:"val",title:"判断是否 FormData 对象",desc:"",params:[],codes:["\n XEUtils.isFormData({}) // false\n XEUtils.isFormData(new FormData()) // true\n "]},{name:"isMap",args:"val",title:"判断是否 Map 对象",desc:"",params:[],codes:["\n XEUtils.isMap({}) // false\n XEUtils.isMap(new Map()) // true\n "]},{name:"isWeakMap",args:"val",title:"判断是否 WeakMap 对象",desc:"",params:[],codes:["\n XEUtils.isWeakMap({}) // false\n XEUtils.isWeakMap(new WeakMap()) // true\n "]},{name:"isSet",args:"val",title:"判断是否 Set 对象",desc:"",params:[],codes:["\n XEUtils.isSet({}) // false\n XEUtils.isSet(new Set()) // true\n "]},{name:"isWeakSet",args:"val",title:"判断是否 WeakSet 对象",desc:"",params:[],codes:["\n XEUtils.isWeakSet({}) // false\n XEUtils.isWeakSet(new WeakSet()) // true\n "]},{name:"isLeapYear",args:"date",title:"判断是否闰年",desc:"",params:[],codes:["\n XEUtils.isLeapYear(1606752000000) // true\n XEUtils.isLeapYear('2018-12-01') // false\n XEUtils.isLeapYear('2020-12-01') // true\n XEUtils.isLeapYear(new Date('2020/12/01')) // true\n "]},{name:"isMatch",args:"obj, source",title:"判断属性中的键和值是否包含在对象中",desc:"",params:[],codes:["\n XEUtils.isMatch({ aa: 11, bb: 22 }, { bb: 22 }) // true\n XEUtils.isMatch({ aa: 11, bb: 22 }, { bb: 33 }) // false\n "]},{name:"isEqual",args:"obj1, obj2",title:"深度比较两个对象之间的值是否相等",desc:"",params:[],codes:["\n XEUtils.isEqual({}, []) // false\n XEUtils.isEqual({0: 1}, [1]) // false\n XEUtils.isEqual({name: 'test1'}, {name: 'test1'}) // true\n XEUtils.isEqual({name: 'test1', list: [11, /\\d/]}, {name: 'test1', list: [11, /\\d/]}) // true\n XEUtils.isEqual({name: 'test1', list: [11, 33, {a: /\\D/}]}, {name: 'test1', list: [11, 33, {a: /\\d/}]}) // false\n "]},{name:"isEqualWith",args:"obj1, obj2, func",title:"深度比较两个对象之间的值是否相等,使用自定义比较函数",desc:"",params:[],codes:["\n XEUtils.isEqualWith({0: 1}, [1]) // false\n XEUtils.isEqualWith({0: 1}, [1], (v1, v2) => true) // true\n XEUtils.isEqualWith([1], [1]) // true\n XEUtils.isEqualWith([1], [1], (v1, v2) => false) // false\n "]},{name:"isDateSame",args:"date1, date2, format",title:"判断两个日期是否相同",desc:"",params:[],codes:["\n XEUtils.isDateSame('2018-12-01', '2018-12-01') // true\n XEUtils.isDateSame(new Date(), '2018-12-01', 'yyyy') // 判断是否同一年 true\n XEUtils.isDateSame(new Date(), XEUtils.toStringDate('12/30/2018', 'MM/dd/yyyy'), 'MM') // 判断是否同一月 true\n XEUtils.isDateSame(new Date(), new Date(), 'dd') // 判断是否同一日 true\n XEUtils.isDateSame(new Date(), new Date(), 'yyyyMMdd') // 判断是否同年同月同日 true\n "]},{name:"getType",args:"obj",title:"获取对象类型",desc:"",params:[],codes:["\n XEUtils.getType() // 'undefined'\n XEUtils.getType(null) // 'null'\n XEUtils.getType('') // 'string'\n XEUtils.getType(/\\d/) // 'regexp'\n XEUtils.getType(1) // 'number'\n XEUtils.getType([]) // 'array'\n XEUtils.getType({}) // 'object'\n XEUtils.getType(new Error()) // 'error'\n XEUtils.getType(function(){}) // 'function'\n "]},{name:"uniqueId",args:"prefix",title:"获取一个全局唯一标识",desc:"",params:[],codes:["\n XEUtils.uniqueId() // 1\n XEUtils.uniqueId() // 2\n XEUtils.uniqueId('prefix_') // 'prefix_3'\n "]},{name:"getSize",args:"obj",title:"返回对象的长度",desc:"",params:[],codes:["\n XEUtils.getSize('123') // 3\n XEUtils.getSize([1, 3]) // 2\n XEUtils.getSize({a: 2, b: 5}) // 2\n "]},{name:"toStringJSON",args:"str",title:"字符串转 JSON",desc:"",params:[],codes:["\n XEUtils.toStringJSON('{\"a\":1}') // {a: 1}\n XEUtils.toStringJSON('[11,22]') // [11, 22]\n "]},{name:"toJSONString",args:"obj",title:"JSON 转字符串",desc:"",params:[],codes:["\n XEUtils.toJSONString({a: 1}) // '{\"a\":1}'\n XEUtils.toJSONString([11, 22]) // '[11,22]'\n "]},{name:"keys",args:"obj",title:"获取对象所有属性",desc:"",params:[],codes:["\n XEUtils.keys({a: 11}) // ['a']\n "]},{name:"values",args:"obj",title:"获取对象所有值",desc:"",params:[],codes:["\n XEUtils.values({a: 11}) // [11]\n "]},{name:"entries",args:"obj",title:"获取对象所有属性、值",desc:"",params:[],codes:["\n XEUtils.entries({a: 11}) // [['a', 11]]\n XEUtils.entries([11, 22]) // [['0', 11], ['1', 22]]\n "]},{name:"first",args:"obj",title:"获取对象第一个值",desc:"",params:[],codes:["\n XEUtils.first({a: 11, b : 22}) // 11\n XEUtils.first([11, 22]) // 11\n "]},{name:"last",args:"obj",title:"获取对象最后一个值",desc:"",params:[],codes:["\n XEUtils.last({a: 11, b: 22}) // 22\n XEUtils.last([11, 22]) // 22\n "]},{name:"each",args:"obj, iterate [, context]",title:"通用迭代器",desc:"",params:[],codes:["\n XEUtils.each([11, 22, 33], (item, key) => {\n // 通用迭代器,支持遍历任意类型\n })\n "]},{name:"lastEach",args:"obj, iterate [, context]",title:"通用迭代器,从最后开始迭代",desc:"",params:[],codes:["\n XEUtils.lastEach([11, 22, 33], (item, key) => {\n // 通用迭代器,支持遍历任意类型\n })\n "]},{name:"range",args:"start, stop, step",title:"序号列表生成函数",desc:"",params:[],codes:["\n XEUtils.range(0) // []\n XEUtils.range(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n XEUtils.range(-5, 5) // [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]\n XEUtils.range(0, 10, 2) // [0, 2, 4, 6, 8]\n "]}]},{label:"Object",value:"object",expand:!0,children:[{name:"has",args:"obj, property",title:"检查键、路径是否是该对象的属性",desc:"",params:[],codes:["\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, 'a.b') // true\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, 'a.e') // false\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, 'a.d[0]') // true\n XEUtils.has({a: {b: 11, c: 22, d: [33, {f: 66}]}}, 'a.d[1].f') // true\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, ['a', 'd[1]']) // true\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, ['a', 'd[3]']) // false\n "]},{name:"get",args:"obj, property, defaultValue",title:"获取对象的属性的值,如果值为 undefined,则返回默认值",desc:"",params:[],codes:["\n XEUtils.get({a: {b: 11, c: 22, d: [33, 44]}}, 'a.b') // 11\n XEUtils.get({a: {b: 11, c: 22, d: [33, 44]}}, 'a.e', 'default') // 'default'\n XEUtils.get({a: {b: 11, c: 22, d: [33, 44]}}, 'a.d[0]') // 33\n XEUtils.get({a: {b: 11, c: 22, d: [33, {f: 66}]}}, 'a.d[1].f') // 66\n XEUtils.get({a: {b: 11, c: 22, d: [33, 44]}}, ['a', 'c']) // 22\n "]},{name:"set",args:"obj, property, value",title:"设置对象属性上的值。如果属性不存在则创建它",desc:"",params:[],codes:["\n XEUtils.set({}, 'a.d[0]', 33) // {a: {d: [33]}}\n XEUtils.set({a: {}}, 'a.d[0].f.h', 44) // {a: {d: [{f: {h: 44}}]}}\n XEUtils.set({}, ['a', 'c'], 22) // {a: {c: 22}}\n XEUtils.set({}, ['a', 'd[0]', 'f', 'h'], 44) // {a: {d: [{f: {h: 44}}]}}\n "]},{name:"clear",args:"obj[, defs, assigns]",title:"清空对象; defs如果不传(清空所有属性)、如果传对象(清空并继承)、如果传值(给所有赋值)",desc:"",params:[],codes:["\n let a = [11, 22, 33, 33]\n XEUtils.clear(a) // []\n XEUtils.clear(a, undefined) // [undefined, undefined, undefined, undefined]\n XEUtils.clear(a, null) // [null, null, null, null]\n let b = {b1: 11, b2: 22}\n XEUtils.clear(b) // {}\n XEUtils.clear(b, undefined) // {b1: undefined, b2: undefined}\n XEUtils.clear(b, null) // {b1: null, b2: null}\n "]},{name:"assign",args:"target, ...sources",title:"将一个或多个源对象复制到目标对象中",desc:"",params:[],codes:["\n const obj1 = {a: 0, b: {b1: 11}}\n const obj2 = XEUtils.assign(obj1, {a: 11}, {c: 33})\n // {a: 11, b: {b1: 11}, c: 33}\n\n const obj3 = {a: 0, b: {b1: 11}}\n const obj4 = XEUtils.assign(obj1, {a: 11, b: {b2: 22}})\n // {a: 11, b: {b2: 22}}\n "]},{name:"merge",args:"target, ...sources",title:"将一个或多个源对象合并到目标对象中,和 assign 的区别是会将对象或数组类型递归合并",desc:"",params:[],codes:["\n const obj1 = [{a: 11}, {b: 22}]\n const obj2 = XEUtils.merge(obj1, [{c: 33}, {d: 44}])\n // [{a: 11, c: 33}, {b: 22, d: 44}]\n\n const obj3 = {a: 0, b: {b1: 11}, c: {c1: {d: 44}}}\n const obj4 = XEUtils.merge(obj1, {a: 11, b: {b2: 22}, c: {f1: 55}})\n // {a: 11, b: {b1: 11, b2: 22}, c: {c1: {d: 44}, f1: 55}}\n "]},{name:"clone",args:"obj, deep",title:"浅拷贝/深拷贝,和 assign 的区别是支持对象的递归克隆",desc:"",params:[],codes:["\n let v1 = {a: 11, b: {b1: 22}}\n let v2 = XEUtils.clone(v1)\n if (v1.b === v2.b) {\n // true\n }\n let v3 = XEUtils.clone(v1, true)\n if (v1.b === v3.b) {\n // false\n }\n "]},{name:"destructuring",args:"obj, ...target",title:"将一个或者多个对象值解构到目标对象",desc:"",params:[],codes:["\n XEUtils.destructuring({a: null}, {a: 11, b: 22, c: 33}) // {a: 11}\n XEUtils.destructuring({a: 11, d: 44}, {a: 11, b: 22, c: 33}) // {a: 11, d: 44}\n XEUtils.destructuring({a: 11, c: 33, d: 44}, {a: 11, b: 22, c: null, e: 55, f: 66}) // {a: 11, c: null, d: 44}\n "]},{name:"objectEach",args:"obj, iterate [, context]",title:"对象迭代器",desc:"",params:[],codes:["\n XEUtils.objectEach([11, 22, 33], (item, key) => {\n // 对象迭代器,只能用于遍历对象,性能高于 each\n })\n "]},{name:"lastObjectEach",args:"obj, iterate [, context]",title:"通用迭代器,从最后开始迭代",desc:"",params:[],codes:["\n XEUtils.lastObjectEach([11, 22, 33], (item, key) => {\n // 对象迭代器,只能用于遍历对象,性能高于 lastEach\n })\n "]},{name:"objectMap",args:"obj, iterate [, context]",title:"指定方法后的返回值组成的新对象",desc:"",params:[],codes:["\n XEUtils.objectMap({a: {type: 'a'}, b: {type: 'b'}}, item => item.type) // {a: \"a\", b: \"b\"}\n "]},{name:"pick",args:"obj, array",title:"根据 keys 过滤指定的属性值 或者 接收一个判断函数,返回一个新的对象",desc:"",params:[],codes:["\n XEUtils.pick({name: 'test11', age: 25, height: 176}, 'name', 'height') // {name: 'test11', height: 176}\n XEUtils.pick({name: 'test11', age: 25, height: 176}, ['name', 'age']) // {name: 'test11', age: 25}\n XEUtils.pick({name: 'test11', age: 25, height: 176}, val => XEUtils.isNumber(val)) // {age: 25, height: 176}\n "]},{name:"omit",args:"obj, array",title:"根据 keys 排除指定的属性值 或者 接收一个判断函数,返回一个新的对象",desc:"",params:[],codes:["\n XEUtils.omit({name: 'test11', age: 25, height: 176}, 'name', 'height') // {age: 25}\n XEUtils.omit({name: 'test11', age: 25, height: 176}, ['name', 'age']) // {height: 176}\n XEUtils.omit({name: 'test11', age: 25, height: 176}, val => XEUtils.isNumber(val)) // {name: 'test11'}\n "]}]},{label:"Function",value:"function",expand:!0,children:[{name:"noop",args:"",title:"一个空的方法,始终返回 undefined,可用于初始化值",desc:"",params:[],codes:["\n [11, 22, 33].map(XEUtils.noop)\n // [undefined, undefined, undefined]\n "]},{name:"delay",args:"callback, wait[, ...arguments]",title:"该方法和 setTimeout 一样的效果,区别就是支持额外参数",desc:"",params:[],codes:["\n XEUtils.delay(function (name) {\n console.log(name)\n }, 300, 'test11')\n // 'test11'\n "]},{name:"bind",args:"callback, context[, ...arguments]",title:"创建一个绑定上下文的函数",desc:"",params:[],codes:["\n let rest = XEUtils.bind(function (val) {\n return this.name + ' = ' + val\n }, {name: 'test'})\n rest(222) // 'test = 222'\n rest(333) // 'test = 333'\n "]},{name:"once",args:"callback, context[, ...arguments]",title:"创建一个只能调用一次的函数,只会返回第一次执行后的结果",desc:"",params:[],codes:["\n let rest = XEUtils.once(function (val) {\n return this.name + ' = ' + val\n }, {name: 'test'})\n rest(222) // 'test = 222'\n rest(333) // 'test = 222'\n "]},{name:"after",args:"count, callback, context",title:"创建一个函数, 调用次数超过 count 次之后执行回调并将所有结果记住后返回",desc:"",params:[],codes:["\n function getJSON (url, callback) {\n setTimeout(function() {\n callback({name: 'test1'})\n }, 200)\n }\n\n // 如果你想确保所有异步请求完成之后才执行这个函数\n let finish = XEUtils.after(3, function (rests) {\n console.log('All finish')\n })\n getJSON('/api/list1', finish)\n getJSON('/api/list2', finish)\n getJSON('/api/list3', finish)\n "]},{name:"before",args:"count, callback, context",title:"创建一个函数, 调用次数不超过 count 次之前执行回调并将所有结果记住后返回",desc:"",params:[],codes:["\n document.querySelector('.btn').addEventListener('click', XEUtils.before(4, function (rests) {\n console.log('只能点击三次')\n }))\n "]},{name:"throttle",args:"callback, wait[, options]",title:"节流函数;当被调用 n 毫秒后才会执行,如果在这时间内又被调用则至少每隔 n 秒毫秒调用一次该函数",desc:"",params:[],codes:["\n function scrollEvent (evnt) {\n console.log('至少每隔wait秒毫秒之内只会调用一次')\n }\n\n // 在计时结束之前执行\n document.body.addEventListener('scroll', XEUtils.throttle(scrollEvent, 100))\n // 在计时结束之前执行\n document.body.addEventListener('scroll', XEUtils.throttle(scrollEvent, 100, {\n leading: true,\n trailing: false\n }))\n // 在计时结束之后执行\n document.body.addEventListener('scroll', XEUtils.throttle(scrollEvent, 100, {\n leading: false,\n trailing: true\n }))\n\n let func = XEUtils.throttle(function (msg) {\n console.log(msg)\n }, 300)\n func('执行一次')\n func.cancel()\n func('取消后中断计时,再次调用会马上执行')\n "]},{name:"debounce",args:"callback, wait[, options]",title:"函数去抖;当被调用 n 毫秒后才会执行,如果在这时间内又被调用则将重新计算执行时间",desc:"",params:[],codes:["\n function resizeEvent (evnt) {\n console.log('如果wait毫秒内重复调用则会重新计时,在函数最后一次调用wait毫秒之后才会执行回调')\n }\n\n // 在计时结束之后执行\n document.addEventListener('resize', XEUtils.debounce(resizeEvent, 100))\n // 在计时结束之前执行\n document.addEventListener('resize', XEUtils.debounce(resizeEvent, 100, true))\n // 在计时结束之前执行\n document.addEventListener('resize', XEUtils.debounce(resizeEvent, 100, {\n leading: true,\n trailing: false\n }))\n // 在计时结束之后执行\n document.addEventListener('resize', XEUtils.debounce(resizeEvent, 100, {\n leading: false,\n trailing: true\n }))\n\n let func = XEUtils.debounce(function (msg) {\n console.log(msg)\n }, 300)\n func('计时结束之前执行一次')\n func.cancel()\n func('取消后中重新计时,在计时结束之前执行')\n "]}]},{label:"Array",value:"array",expand:!0,children:[{name:"arrayEach",args:"obj, iterate [, context]",title:"数组迭代器",desc:"",params:[],codes:["\n XEUtils.arrayEach([11, 22, 33], (item, key) => {\n // 数组迭代器,只能用于遍历(数组或伪数组),性能高于 each\n })\n "]},{name:"lastArrayEach",args:"obj, iterate [, context]",title:" 数组迭代器,从最后开始迭代",desc:"",params:[],codes:["\n XEUtils.lastArrayEach([11, 22, 33], (item, key) => {\n // 数组迭代器,只能用于遍历(数组或伪数组),性能高于 lastEach\n })\n "]},{name:"slice",args:"array, start, end",title:"裁剪(数组或伪数组),从 start 位置开始到 end 结束,但不包括 end 本身的位置",desc:"",params:[],codes:["\n XEUtils.slice([11, 22, 33, 44], 1) // [22, 33, 44]\n XEUtils.slice([11, 22, 33, 44], 1, 3) // [22, 33]\n function method () {\n XEUtils.slice(arguments, 1, 3) // [22, 33]\n }\n method(11, 22, 33, 44)\n "]},{name:"indexOf",args:"obj, val",title:"返回对象第一个索引值",desc:"",params:[],codes:["\n XEUtils.indexOf([11, 22, 33, 22], 55) // -1\n XEUtils.indexOf([11, 22, 33, 22], 22) // 1\n "]},{name:"arrayIndexOf",args:"obj, val",title:"返回数组第一个索引值,比 indexOf 快",desc:"",params:[],codes:["\n XEUtils.arrayIndexOf([11, 22, 33, 22], 55) // -1\n XEUtils.arrayIndexOf([11, 22, 33, 22], 22) // 1\n "]},{name:"findIndexOf",args:"obj, iterate [, context]",title:"返回对象第一个索引值",desc:"",params:[],codes:["\n XEUtils.findIndexOf([11, 22, 33, 22], item => item === 55) // -1\n XEUtils.findIndexOf([11, 22, 33, 22], item => item === 22) // 1\n "]},{name:"lastIndexOf",args:"obj, val",title:"从最后开始的索引值,返回对象第一个索引值",desc:"",params:[],codes:["\n XEUtils.lastIndexOf([11, 22, 33, 22], 55) // -1\n XEUtils.lastIndexOf([11, 22, 33, 22], 22) // 3\n "]},{name:"arrayLastIndexOf",args:"obj, val",title:"从最后开始的索引值,返回数组第一个索引值,比 indexOf 快",desc:"",params:[],codes:["\n XEUtils.arrayLastIndexOf([11, 22, 33, 22], 55) // -1\n XEUtils.arrayLastIndexOf([11, 22, 33, 22], 22) // 3\n "]},{name:"findLastIndexOf",args:"obj, iterate [, context]",title:"从最后开始的索引值,返回对象第一个索引值",desc:"",params:[],codes:["\n XEUtils.findLastIndexOf([11, 22, 33, 22], item => item === 55) // -1\n XEUtils.findLastIndexOf([11, 22, 33, 22], item => item === 22) // 3\n "]},{name:"includes",args:"obj, val",title:"判断对象是否包含该值,成功返回 true 否则 false",desc:"",params:[],codes:["\n XEUtils.includes([11], 22) // false\n XEUtils.includes([11, 22], 22) // true\n "]},{name:"includeArrays",args:"array1, array2",title:"判断数组是否包含另一数组",desc:"",params:[],codes:["\n XEUtils.includeArrays([11, 22, 33], []) // true\n XEUtils.includeArrays([11, 22, 33], [11]) // true\n XEUtils.includeArrays([11, 22, 33], [22, 33]) // true\n XEUtils.includeArrays([11, 22, 33], [22, 44]) // false\n "]},{name:"remove",args:"obj, iterate",title:"移除对象属性",desc:"",params:[],codes:["\n let list1 = [11, 22, 33, 44]\n XEUtils.remove(list1, 2) // list1 = [11, 22, 44]\n let list2 = [11, 22, 33, 44]\n XEUtils.remove(list2, item => item === 22) // list2 = [11, 33, 44]\n "]},{name:"orderBy | sortBy",args:"arr, fieldConfs [, context]",title:"将数组进行排序",desc:"",codes:['\n // 数值排序\n XEUtils.orderBy([11, 55, 99, 77, 11, 55, 22])\n // [11,11,22,55,55,77,99]\n XEUtils.orderBy([11, 55, 99, 77, 11, 55, 22], { order: \'desc\' })\n // [99, 77, 55, 55, 22, 11, 11]\n\n // 字母排序\n XEUtils.orderBy([\'x\', \'z\', \'g\', \'q\', \'e\', \'b\', \'a\', \'g\', \'f\', \'c\', \'j\'])\n // ["a","b","c","e","f","g","g","j","q","x","z"]\n\n // 中文排序\n XEUtils.orderBy([\'小\', \'何\', \'李\', \'林\', \'有\', \'好\', \'啊\', \'的\', \'出\', \'库\', \'徐\'])\n // ["啊","出","的","好","何","库","李","林","小","徐","有"]\n\n // 深层对象\n XEUtils.orderBy([{ age: 27 }, { age: 26 }, { age: 28 }], \'age\')\n // [{"age":26},{"age":27},{"age":28}]\n XEUtils.orderBy([{ age: 27 }, { age: 26 }, { age: 28 }], [[\'age\', \'asc\']])\n // [{"age":26},{"age":27},{"age":28}]\n\n // 多字段排序\n XEUtils.orderBy([\n { name: \'x\', age: 26 },\n { name: \'d\', age: 27 },\n { name: \'z\', age: 26 },\n { name: \'z\', age: 24 },\n { name: \'z\', age: 25 }\n ], [[\'age\', \'asc\'], [\'name\', \'desc\']])\n // [{"name":"z","age":24},{"name":"z","age":25},{"name":"z","age":26},{"name":"x","age":26},{"name":"d","age":27}]\n\n // 自定义组合排序\n XEUtils.orderBy([\n { name: \'x\', age: 26 },\n { name: \'d\', age: 27 },\n { name: \'x\', age: 26 },\n { name: \'z\', age: 26 }\n ], [[item => item.name, \'asc\'], [item => item.age, \'desc\']])\n // [{"name":"d","age":27},{"name":"x","age":26},{"name":"x","age":26},{"name":"z","age":26}]\n ']},{name:"shuffle",args:"array",title:"将一个数组随机打乱,返回一个新的数组",desc:"",params:[],codes:["\n XEUtils.shuffle([11, 22, 33, 44, 55]) // [22, 33, 55, 11, 44]\n "]},{name:"sample",args:"array, number",title:"从一个数组中随机返回几个元素",desc:"",params:[],codes:["\n XEUtils.sample([11, 22, 33, 44, 55], 3) // [22, 33, 55]\n "]},{name:"some",args:"obj, iterate [, context]",title:"对象中的值中的每一项运行给定函数,如果函数对任一项返回 true,则返回 true,否则返回 false",desc:"",params:[],codes:["\n XEUtils.some([{value: 11}, {value: 22}], item => item.value === 55) // false\n "]},{name:"every",args:"obj, iterate [, context]",title:" 对象中的值中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true,否则返回 false",desc:"",params:[],codes:["\n XEUtils.every([{value: 11}, {value: 22}], item => item.value === 11) // false\n "]},{name:"filter",args:"obj, iterate [, context]",title:"根据回调过滤数据",desc:"",params:[],codes:["\n XEUtils.filter([{value: 11}, {value: 22}], item => item.value > 11) // [{value: 22}]\n "]},{name:"find",args:"obj, iterate [, context]",title:"查找匹配第一条数据",desc:"",params:[],codes:["\n XEUtils.find([{value: 11}, {value: 22}], item => item.value === 55) // null\n "]},{name:"findKey",args:"obj, iterate [, context]",title:"查找匹配第一条数据的键",desc:"",params:[],codes:["\n XEUtils.findKey([{value: 11}, {value: 22}], item => item.value === 22) // '1'\n XEUtils.findKey({aa: 11, bb: 22, cc: 33}, item => item === 22) // 'bb'\n "]},{name:"map",args:"obj, iterate [, context]",title:"指定方法后的返回值组成的新数组",desc:"",params:[],codes:["\n XEUtils.map([{value: 11}, {value: 22}], item => item.value) // [11, 22]\n "]},{name:"copyWithin",args:"array, target, start [, end]",title:"浅复制数组的一部分到同一数组中的另一个位置,数组大小不变",desc:"",params:[],codes:["\n XEUtils.copyWithin([11, 22, 33, 44], 0, 2) // [33, 44, 33, 44]\n XEUtils.copyWithin([11, 22, 33, 44], 0, -1) // [44, 22, 33, 44]\n "]},{name:"sum",args:"obj, iterate [, context]",title:"求和函数,将数值相加",desc:"",params:[],codes:["\n XEUtils.sum([22, 66, 88]) // 176\n XEUtils.sum([{value: 11}, {value: 22}, {value: 66}], 'value') // 99\n XEUtils.sum({val1: 21, val2: 34, val3: 47}) // 102\n "]},{name:"mean",args:"obj, iterate [, context]",title:" 求平均值函数",desc:"",params:[],codes:["\n XEUtils.mean({ val1: 21, val2: 34, val3: 47 }) // 34\n XEUtils.mean([22, 66, 60, 60]) // 52\n XEUtils.mean([{value: 34}, {value: 22}], 'value') // 28\n XEUtils.mean([{value: 11}, {value: 22}, {value: 66}], item => item.value * 2) // 66\n XEUtils.mean({val1: 21, val2: 34, val3: 45, val4: 55}) // 38.75\n "]},{name:"toArray",args:"array",title:"将对象或者伪数组转为新数组",desc:"",params:[],codes:["\n XEUtils.toArray([]) // []\n XEUtils.toArray({}) // []\n XEUtils.toArray({name: 'test1', age: 25}) // ['test1', 25]\n XEUtils.toArray(arguments) // [...]\n XEUtils.toArray(document.querySelectorAll('div')) // [...]\n "]},{name:"reduce",args:"array, iterate [, initialValue]",title:"接收一个函数作为累加器,数组中的每个值(从左到右)开始合并,最终为一个值",desc:"",params:[],codes:["\n XEUtils.reduce([22, 66, 88], (previous, item) => previous + item) // 176\n "]},{name:"zip",args:"...[]",title:"将每个数组中相应位置的值合并在一起",desc:"",params:[],codes:["\n XEUtils.zip(['name1', 'name2', 'name3'], [true, true, false], [30, 40, 20])\n // [['name1', true, 30], ['name2', true, 40], ['name3', false, 20]]\n "]},{name:"unzip",args:"arrays",title:"与 zip 相反",desc:"",params:[],codes:["\n XEUtils.unzip([['name1', true, 30], ['name2', true, 40], ['name3', false, 20]])\n // [['name1', 'name2', 'name3'], [true, true, false], [30, 40, 20]]\n "]},{name:"zipObject",args:"props, values",title:"根据键数组、值数组对转换为对象",desc:"",params:[],codes:["\n XEUtils.zipObject(['aa', 'bb', 'cc'], [11, 22, 33])\n // { aa: 11, bb: 22, cc: 33 }\n "]},{name:"uniq",args:"array",title:" 数组去重",desc:"",params:[],codes:["\n XEUtils.uniq([11, 22, 33, 33, 22, 55]) // [11, 22, 33, 55]\n "]},{name:"union",args:"...array",title:"将多个数的值返回唯一的并集数组",desc:"",params:[],codes:["\n XEUtils.union([11, 22], [33, 22], [44, 11]) // [11, 22, 33, 44]\n "]},{name:"flatten",args:"array, deep",title:"将一个多维数组拍平",desc:"",params:[],codes:["\n XEUtils.flatten([[1, 2, 3], [4, 5, 6], [7, 8]])\n // [1, 2, 3, 4, 5, 6, 7, 8]\n "]},{name:"chunk",args:"array, size",title:"将一个数组分割成大小的组。如果数组不能被平均分配,那么最后一块将是剩下的元素",desc:"",params:[],codes:["\n XEUtils.chunk(['a', 'b', 'c', 'd'], 2) // [['a', 'b'], ['c', 'd']]\n XEUtils.chunk(['a', 'b', 'c', 'd'], 3) // [['a', 'b', 'c'], ['d']]\n "]},{name:"property",args:"path",title:"返回一个获取对象属性的函数",desc:"",params:[],codes:["\n let getName = XEUtils.property('name')\n getName({name: 'test11', age: 25, height: 176}) // 'test11'\n getName({age: 25, height: 176}) // undefined\n "]},{name:"pluck",args:"array, key",title:"获取数组对象中某属性值,返回一个数组",desc:"",params:[],codes:["\n XEUtils.pluck([{a: 11, b: 22}, {a: 33, b: 44}], 'a') // [11, 33]\n XEUtils.pluck([[11, 22, 33], [44, 55, 66]], 1) // [22, 55]\n "]},{name:"invoke",args:"list, path, ...arguments",title:"在list的每个元素上执行方法,任何传递的额外参数都会在调用方法的时候传递给它",desc:"",params:[],codes:["\n XEUtils.invoke([[3, 1, 6, 7], [3, 2, 1, 8]], 'sort') // [[1, 3, 6, 7], [1, 2, 3, 8]]\n XEUtils.invoke(['123', '456'], 'split') // [['123'], ['456']]\n XEUtils.invoke([123, 456], String.prototype.split, '') // [['1', '2', '3'], ['4', '5', '6']]\n XEUtils.invoke([{a: {b: [2, 0, 1]}}, {a: {b: [2, 1]}}, {a: {b: [4, 8, 1]}}], ['a', 'b', 'sort'])\n // [[0, 1, 2], [1, 2], [1, 4, 8]]\n "]},{name:"groupBy",args:"obj, iterate [, context]",title:"集合分组,默认使用键值分组,如果有 iterate 则使用结果进行分组",desc:"",params:[],codes:["\n XEUtils.groupBy([{type: 'a'}, {type: 'b'}], 'type') // {a: [{type: 'a'}], b: [{type: 'b'}]}\n XEUtils.groupBy([{type: 'a'}, {type: 'a'}, {type: 'b'}], 'type')\n // {a: [{type: 'a'}, {type: 'a'}], b: [{type: 'b'}]}\n "]},{name:"countBy",args:"obj, iterate [, context]",title:"集合分组统计,返回各组中对象的数量统计",desc:"",params:[],codes:["\n XEUtils.countBy([{type: 'a'}, {type: 'b'}], 'type') // {a: 1, b: 1}\n XEUtils.countBy([{type: 'a'}, {type: 'a'}, {type: 'b'}], 'type') // {a: 2, b: 1}\n "]},{name:"toArrayTree",args:"array, options",title:"一个高性能的树结构转换函数,将一个带层级的数据列表转成树结构",desc:"",params:[["属性","描述","默认值"],["strict","是否严格模式,会去掉父子关联不存在数据,当子节点为空时将没有 children 属性","false"],["key","节点键值","id"],["parentKey","父节点键值","parentId"],["children","子节点属性","children"],["mapChildren","子节点映射属性",""],["sortKey","对树节点进行排序属性",""],["reverse","sortKey不为空是有效,默认升序","false"],["data","数据存放属性","null"]],codes:['\n // 默认树结构\n let list1 = [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 3, name: \'333\'},\n {id: 4, parentId: 2, name: \'444\'}\n ]\n XEUtils.toArrayTree(list1)\n /*\n [\n {\n "id":1,\n "name":"111",\n "children":[\n {\n "id":2,\n "parentId":1,\n "name":"222",\n "children":[\n {\n "id":4,\n "parentId":2,\n "name":"444",\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "id":3,\n "name":"333",\n "children":[]\n }\n ]\n */\n\n // 返回带排序的树结构\n let list2 = [\n {id: 1, name: \'111\', seq: 5},\n {id: 2, parentId: 1, name: \'222\', seq: 3},\n {id: 3, name: \'333\', seq: 6},\n {id: 4, parentId: 2, name: \'444\', seq: 2},\n {id: 5, parentId: 1, name: \'555\', seq: 1}\n ]\n XEUtils.toArrayTree(list2, {sortKey: \'seq\'})\n /*\n [\n {\n "id":1,\n "name":"111",\n "seq":5,\n "children":[\n {\n "id":5,\n "parentId":1,\n "name":"555",\n "seq":1,\n "children":[]\n },\n {\n "id":2,\n "parentId":1,\n "name":"222",\n "seq":3,\n "children":[\n {\n "id":4,\n "parentId":2\n ,"name":"444",\n "seq":2,\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "id":3,\n "name":"333",\n "seq":6,\n "children":[]\n }\n ]\n */\n\n // 自定义数据存放属性\n let list3 = [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 3, name: \'333\'},\n {id: 4, parentId: 2, name: \'444\'},\n {id: 5, parentId: 22, name: \'555\'}\n ]\n XEUtils.toArrayTree(list3, {data: \'data\'})\n /*\n [\n {\n "data":{"id":1,"name":"111"},\n "id":1,\n "children":[\n {\n "data":{"id":2,"parentId":1,"name":"222"},\n "id":2,\n "parentId":1,\n "children":[\n {\n "data":{"id":4,"parentId":2,"name":"444"},\n "id":4,\n "parentId":2,\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "data":{"id":3,"name":"333"},\n "id":3,\n "children":[]\n },\n {\n "data":{"id":5,"parentId":22,"name":"555"},\n "id":5,\n "parentId":22,\n "children":[]\n }\n ]\n */\n\n // 如果设置为严格模式,(非父子关联及冗余)的数据会被忽略\n let list4 = [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 3, name: \'333\'},\n {id: 4, parentId: 2, name: \'444\'},\n {id: 5, parentId: 22, name: \'555\'}\n ]\n XEUtils.toArrayTree(list4, {strict: true, parentKey: \'parentId\', key: \'id\', children: \'children\', data: \'data\'})\n /*\n [\n {\n "data":{"id":1,"name":"111"},\n "id":1,\n "children":[\n {\n "data":{"id":2,"parentId":1,"name":"222"},\n "id":2,\n "parentId":1,\n "children":[\n {\n "data":{"id":4,"parentId":2,"name":"444"},\n "id":4,\n "parentId":2,\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "data":{"id":3,"name":"333"},\n "id":3,\n "children":[]\n }\n ]\n */\n ']},{name:"toTreeArray",args:"array, options",title:"将一个树结构转成数组列表",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"],["data","数据存放属性",""],["clear","同时移除子节点属性","false"]],codes:['\n let list1 = [\n {\n "id":1,\n "name":"111",\n "children":[\n {\n "id":2,\n "parentId":1,\n "name":"222",\n "children":[\n {\n "id":4,\n "parentId":2,\n "name":"444",\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "id":3,\n "name":"333",\n "children":[]\n }\n ]\n XEUtils.toTreeArray(list1)\n /*\n [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 4, parentId: 2, name: \'444\'}\n {id: 3, name: \'333\'}\n ]\n */\n\n let list2 = [\n {\n "data":{"id":1,"name":"111"},\n "id":1,\n "children":[\n {\n "data":{"id":2,"parentId":1,"name":"222"},\n "id":2,\n "parentId":1,\n "children":[\n {\n "data":{"id":4,"parentId":2,"name":"444"},\n "id":4,\n "parentId":2,\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "data":{"id":3,"name":"333"},\n "id":3,\n "children":[]\n },\n {\n "data":{"id":5,"parentId":22,"name":"555"},\n "id":5,\n "parentId":22,\n "children":[]\n }\n ]\n XEUtils.toTreeArray(list2, {data: \'data\'})\n /*\n [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 4, parentId: 2, name: \'444\'},\n {id: 3, name: \'333\'},\n {id: 5, parentId: 22, name: \'555\'}\n ]\n */\n ']},{name:"findTree",args:"obj, iterate[, options, context]",title:"从树结构中查找匹配第一条数据的键、值、路径",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n children: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.findTree(tree1, item => item.id === 20) // { item: {id: 20}, ... }\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.findTree(tree2, item => item.id === 20, { children: 'childs' }) // { item: {id: 20}, ... }\n "]},{name:"eachTree",args:"obj, iterate[, options, context]",title:"从树结构中遍历数据的键、值、路径",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n children: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.eachTree(tree1, item => {\n // ...\n })\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.eachTree(tree2, item => {\n // ...\n }, { children: 'childs' })\n "]},{name:"mapTree",args:"obj, iterate[, options, context]",title:"从树结构中指定方法后的返回值组成的新数组",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"],["mapChildren","将子节点映射到指定的属性",""]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 20 }\n ]\n }, {\n id: 3,\n children: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.mapTree(tree1, item => {\n return {\n id: item.id * 2\n }\n })\n // [\n // { id: 2 },\n // {\n // id: 4,\n // children: [\n // { id: 40 }\n // ]\n // }, {\n // id: 6,\n // children: [\n // { id: 60 }\n // ]\n // }\n // ]\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.mapTree(tree2, item => {\n return {\n id: item.id * 2\n }\n }, {children: 'childs'})\n // [\n // { id: 2 },\n // {\n // id: 4,\n // childs: [\n // { id: 40 }\n // ]\n // },\n // {\n // id: 6,\n // childs: [\n // { id: 60 }\n // ]\n // }\n // ]\n\n var tree3 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.mapTree(tree3, item => {\n return {\n id: item.id * 2\n }\n }, { children: 'childs', mapChildren: 'list' })\n // [\n // { id: 2 },\n // {\n // id: 4,\n // list: [\n // { id: 40 }\n // ]\n // },\n // {\n // id: 6,\n // list: [\n // { id: 60 }\n // ]\n // }\n // ]\n "]},{name:"filterTree",args:"obj, iterate[, options, context]",title:"从树结构中根据回调过滤数据",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n children: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.filterTree(tree1, item => item.id === 1) \n // { id: 1 }\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.filterTree(tree2, item => item.id >= 3, {children: 'childs'}) \n // [\n // {\n // id: 3,\n // childs: [\n // { id: 30 }\n // ]\n // }\n // ]\n "]},{name:"searchTree",args:"obj, iterate[, options, context]",title:"从树结构中根据回调查找数据",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"],["mapChildren","将子节点映射到指定的属性",""],["original","是否源对象地址引用(谨慎!源数据将被破坏)","false"]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 0 }\n ]\n },\n {\n id: 3,\n children: [\n {\n id: 30,\n children: [\n { id: 3001 }\n ]\n },\n { id: 31 }\n ]\n }\n ]\n XEUtils.searchTree(tree1, item => item.id === 3)\n // [\n // {\n // id: 3,\n // children: [\n // {\n // id: 30,\n // children: [\n // { id: 3001 }\n // ]\n // },\n // { id: 31 }\n // ]\n // }\n // ]\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 0 }\n ]\n },\n {\n id: 3,\n childs: [\n {\n id: 30,\n childs: [\n { id: 3001 }\n ]\n },\n { id: 31 }\n ]\n }\n ]\n XEUtils.searchTree(tree2, item => item.id === 30, { children: 'childs' })\n // [\n // {\n // id: 3,\n // childs: [\n // {\n // id: 30,\n // childs: [\n // { id: 3001 }\n // ]\n // }\n // ]\n // }\n // ]\n\n var tree3 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 0 }\n ]\n },\n {\n id: 3,\n childs: [\n {\n id: 30,\n childs: [\n { id: 3001 }\n ]\n },\n { id: 31 }\n ]\n }\n ]\n XEUtils.searchTree(tree3, item => item.id === 30, { children: 'childs', mapChildren: 'list' })\n // [\n // {\n // id: 3,\n // childs: [\n // {\n // id: 30,\n // childs: [\n // { id: 3001 }\n // ]\n // },\n // { id: 31 }\n // ]\n // list: [\n // {\n // id: 30,\n // list: [\n // { id: 3001 }\n // ]\n // }\n // ]\n // }\n // ]\n "]}]},{label:"Date",value:"date",expand:!0,children:[{name:"now",args:"",title:"返回当前时间戳",desc:"",params:[],codes:["\n XEUtils.now() // Date.now() 获取当前时间戳 1514096716800\n "]},{name:"timestamp",args:"date[, format]",title:"将日期转为时间戳",desc:"",params:[],codes:["\n XEUtils.timestamp() // XEUtils.now() = Date.now() 获取当前时间戳 1514096716800\n XEUtils.timestamp(new Date()) // 1514096716800\n XEUtils.timestamp('2018-12-01') // 1543593600000\n XEUtils.timestamp('2017/12/20 10:10:30.459', 'yyyy/MM/dd HH:mm:ss.SSS') // 1513735830459\n "]},{name:"toStringDate",args:"str, format",title:"任意格式字符串转为日期",desc:"",params:[["属性","描述"],["yyyy","年份"],["MM","月份"],["dd","日"],["HH","小时"],["mm","分钟"],["ss","秒"],["SSS","毫秒"],["Z","时区"]],codes:["\n XEUtils.toStringDate('12/20/2017')\n // 如果解析错误则返回 'Invalid Date'\n XEUtils.toStringDate('2017-12-20')\n // Wed Dec 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('2017-12-20 10:10:30')\n // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('2017-12-20T10:10:30.738+0800')\n // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('2017-12-20T10:10:30.738+01:00')\n // Wed Dec 20 2017 17:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('2017-12-20T10:10:30.738Z')\n // Wed Dec 20 2017 18:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('12/20/2017', 'MM/dd/yyyy')\n // Wed Dec 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('20171220101030', 'yyyyMMddHHmmss')\n // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('2017/12/20 10:10:30', 'yyyy/MM/dd HH:mm:ss')\n // Wed Dec 20 2017 10:10:00 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('12/20/2017 10:10:30.100', 'MM/dd/yyyy HH:mm:ss.SSS')\n // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间)\n "]},{name:"toDateString",args:"date [, format, options]",title:"日期格式化为任意格式字符串",desc:"",params:[["属性","描述","备注","值的范围"],["yy","年份","自动截取后两位",""],["yyyy","年份","",""],["M","月份","","1~12"],["MM","月份","自动补0","01~12"],["d","日","","1~31"],["dd","日","自动补0","01~31"],["h","12小时制","","1~12"],["hh","12小时制","自动补0"," 01~12"],["H","24小时制","","0~23"],["HH","24小时制","自动补0","00~23"],["m","分钟","","0~59"],["mm","分钟","自动补0","00~59"],["s","秒","","0~59"],["ss","秒","自动补0","00~59"],["S","毫秒","","0~999"],["SSS","毫秒","自动补0","000~999"],["a","am/pm,小写","","am/pm"],["A","AM/PM,大写","","AM/PM"],["D","年份的第几天","","1~366"],["DDD","年份的第几天","自动补0","001~366"],["e","星期几","","0~6"],["E","星期几","","1~7"],["q","季度","","1~4"],["W","年的第几周","","1~53"],["WW","年的第几周","自动补0",""],["Z","时区值","","[+-]HH:mm"],["ZZ","时区值","","[+-]HHmm"]],codes:["\n XEUtils.toDateString(1483250730000)\n // '2017-01-01 14:05:30'\n XEUtils.toDateString(new Date())\n // '2017-01-01 14:05:30'\n XEUtils.toDateString('2017-01-01 10:05:30', 'MM/dd/yyyy')\n // '01/01/2017'\n XEUtils.toDateString('2017-01-01 10:05:30', 'M/d/yyyy')\n // '1/1/2017'\n XEUtils.toDateString(new Date(), 'yyyyMMddHHmmssSSS')\n // '20170101140530099'\n XEUtils.toDateString(new Date(), 'yyyy-MM-dd HH:mm:ss.SSS')\n // '2017-01-01 14:05:30.099'\n XEUtils.toDateString(new Date(), 'yyyy-MM-dd hh:mm:ss.SSS GMTZ')\n // '2017-01-01 02:05:30.099 GMT+08:00'\n XEUtils.toDateString(new Date(), 'yyyy-MM-dd hh:mm:ss.SSS GMTZZ')\n // '2017-01-01 02:05:30.099 GMT+0800'\n XEUtils.toDateString(new Date(), 'yyyy-M-d h:m:s.S')\n // '2017-1-1 2:5:30.99'\n XEUtils.toDateString(new Date(), 'yyyy年MM月dd日 HH时mm分ss秒S毫秒,星期E 第q季度')\n // '2017年01月01日 14时05分30秒99毫秒,星期0 第1季度'\n XEUtils.toDateString(new Date(), 'yy年M月d日 HH时m分s秒S毫秒,星期E 第q季度')\n // '17年1月1日 14时5分30秒99毫秒,星期0 第1季度'\n XEUtils.toDateString(new Date(), 'yyyy年MM月dd日 hh时mm分ss秒SSS毫秒 ZZ 星期E e 第q季 今年第D天 a A')\n // '2017年01月01日 02时05分30秒099毫秒 +0800 星期0 -1 第1季 今年第1天 pm PM'\n XEUtils.toDateString(new Date(), '[yyyy-MM] yyyy-MM-dd')\n // 'yyyy-MM 2017-01-01'\n "]},{name:"getWhatYear",args:"date, year [, month]",title:"返回前几年或后几年的日期,可以指定年的最初时间(first)、年的最后时间(last)、年的月份(0~11),默认当前",desc:"",params:[],codes:["\n XEUtils.getWhatYear(new Date(), -1) // Mon Nov 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear(1513735830000, -1) // Tue Dec 20 2016 10:10:30 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear('2017-12-20', -1) // Tue Dec 20 2016 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear('2017-12-20', 1) // Thu Dec 20 2018 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear('2017-12-20', 0, 'first') // Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear('2017-12-20', 0, 'last') // Sun Dec 31 2017 23:59:59 GMT+0800 (中国标准时间)\n "]},{name:"getWhatMonth",args:"date, month [, day]",title:"返回前几月或后几月的日期,可以指定月初(first)、月末(last)、天数,默认当前",desc:"",params:[],codes:["\n XEUtils.getWhatMonth(new Date(), -1) // Mon Nov 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth(1513735830000, -1) // Mon Nov 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth('2017-12-20', -1) // Mon Nov 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth('2017-12-20', 1) // Sat Jan 20 2018 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth('2017-12-20', -1, 'first') // Wed Nov 01 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth('2017-12-20', 1, 'last') // Wed Jan 31 2018 23:59:59 GMT+0800 (中国标准时间)\n "]},{name:"getWhatWeek",args:"date, week [, day]",title:"返回前几周或后几周的日期,可以指定星期几(0~6),默认当前",desc:"",params:[],codes:["\n XEUtils.getWhatWeek(new Date(), -1) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek(1513735830000, -1) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', -1) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', 1) // Sun Dec 31 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', -1, 5) // Fri Dec 15 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', 1, 0) // Sun Dec 31 2017 00:00:00 GMT+0800 (中国标准时间)\n "]},{name:"getWhatDay",args:"date, day [, mode]",title:"返回前几天或后几天的日期,可以指定当天最初时间(first)、当天的最后时间(last)",desc:"",params:[],codes:["\n XEUtils.getWhatDay(new Date(), -1) // Tue Dec 19 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay(1513735830000, -1) // Tue Dec 19 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay('2017-12-20', -1) // Tue Dec 19 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay('2017-12-20', 1) // Tue Dec 21 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay('2017-12-20', 0, 'first') // Wed Dec 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay('2017-12-20', 0, 'last') // Wed Dec 20 2017 23:59:59 GMT+0800 (中国标准时间)\n "]},{name:"getDayOfYear",args:"date [, year]",title:"返回某个年份的天数,可以指定前几个年或后几个年,默认当前",desc:"",params:[],codes:["\n XEUtils.getDayOfYear(new Date()) // 365\n XEUtils.getDayOfYear(1513735830000) // 365\n XEUtils.getDayOfYear('2017-12-20') // 365\n XEUtils.getDayOfYear('2019-12-20', 1) // 366\n XEUtils.getDayOfYear('2020-12-20') // 366\n "]},{name:"getYearDay",args:"date",title:"返回某个年份的第几天",desc:"",params:[],codes:["\n XEUtils.getYearDay(new Date()) // 149\n XEUtils.getYearDay('2017-01-20') // 20\n XEUtils.getYearDay('2018-05-20') // 140\n "]},{name:"getYearWeek",args:"date",title:"返回某个年份的第几周",desc:"",params:[],codes:["\n XEUtils.getYearWeek(new Date()) // 22\n XEUtils.getYearWeek('2017-01-20') // 3\n XEUtils.getYearWeek('2018-05-20') // 20\n "]},{name:"getMonthWeek",args:"date",title:"返回某个月份的第几周",desc:"",params:[],codes:["\n XEUtils.getMonthWeek(new Date()) // 4\n XEUtils.getMonthWeek('2017-01-20') // 3\n XEUtils.getMonthWeek('2018-05-20') // 2\n "]},{name:"getDayOfMonth",args:"date [, month]",title:"返回某个月份的天数,可以指定前几个月或后几个月,默认当前",desc:"",params:[],codes:["\n XEUtils.getDayOfMonth(new Date()) // 31\n XEUtils.getDayOfMonth(1513735830000) // 31\n XEUtils.getDayOfMonth('2017-12-20') // 31\n XEUtils.getDayOfMonth('2017-12-20', -1) // 30\n XEUtils.getDayOfMonth('2017-12-20', 1) // 31\n "]},{name:"getDateDiff",args:"startDate, endDate [, rules]",title:"返回两个日期之间差距,如果结束日期小于开始日期 done 为 fasle",desc:"",params:[],codes:["\n XEUtils.getDateDiff('2017-11-20', '2017-12-21')\n // { done: true, time: 2678400000, yyyy: 0, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, S: 0 }\n XEUtils.getDateDiff('2017-12-20', '2017-12-21')\n // { done: true, time: 86400000, yyyy: 0, MM: 0, dd: 1, HH: 0, mm: 0, ss: 0, S: 0 }\n XEUtils.getDateDiff('2018-01-01', '2017-12-21')\n // { done: false, time: 0 }\n let dateDiff = XEUtils.getDateDiff('2017-12-20 10:10:30', '2017-12-21 10:15:00')\n let content = `${dateDiff.mm}分${dateDiff.ss}秒`\n // '4分30秒'\n "]}]},{label:"Number",value:"number",expand:!0,children:[{name:"random",args:"min, max",title:"获取一个指定范围内随机数",desc:"",params:[],codes:["\n XEUtils.random() // 0 ~ 9\n XEUtils.random(3, 6) // 3 ~ 6\n XEUtils.random(0, 5) // 0 ~ 5\n XEUtils.random(10, 100) // 10 ~ 100\n "]},{name:"min",args:"array [, iterate]",title:"获取最小值",desc:"",params:[],codes:["\n XEUtils.min([22, 66, 77, 11]) // 11\n XEUtils.min([{a: 11}, {a: 44}], 'a') // {a: 11}\n XEUtils.min([{a: 11}, {a: 44}], item => item.a) // {a: 11}\n "]},{name:"max",args:"array [, iterate]",title:"获取最大值",desc:"",params:[],codes:["\n XEUtils.max([22, 66, 77, 11]) // 77\n XEUtils.max([{a: 11}, {a: 44}], 'a') // {a: 44}\n XEUtils.max([{a: 11}, {a: 44}], item => item.a) // {a: 44}\n "]},{name:"round",args:"num, digits",title:"将数值四舍五入",desc:"",params:[],codes:["\n XEUtils.round(123.455, 2) // 123.46\n XEUtils.round(123.452, 2) // 123.45\n "]},{name:"ceil",args:"num, digits",title:"将数值向上舍入",desc:"",params:[],codes:["\n XEUtils.ceil(123.455, 2) // 123.46\n XEUtils.ceil(123.452, 2) // 123.46\n "]},{name:"floor",args:"num, digits",title:"将数值向下舍入",desc:"",params:[],codes:["\n XEUtils.floor(123.455, 2) // 123.45\n XEUtils.floor(123.452, 2) // 123.45\n "]},{name:"toFixed",args:"num, digits",title:"将数值四舍五入,并格式化为字符串",desc:"",params:[],codes:["\n XEUtils.toFixed(123.455, 2) // 123.45\n XEUtils.toFixed(123.452, 2) // 123.45\n XEUtils.toFixed(123.452, 4) // 123.4520\n "]},{name:"commafy",args:"num [, options]",title:"数值千分位分隔符、小数点",desc:"",params:[["属性","描述","类型","版本"],["spaceNumber","分割位数,默认3","number",""],["separator","分隔符,默认","string",""],["digits","只对 number 类型有效,小数位数","number","v2+"],["round","只对 number 类型有效,四舍五入,默认true","boolean","v2.7+"],["ceil","只对 number 类型有效,向上舍入","boolean","v2.7+"],["floor","只对 number 类型有效,向下舍入","boolean","v2.7+"]],codes:["\n // 千分位格式化\n XEUtils.commafy(1000000) // '1,000,000'\n // 格式化金额\n XEUtils.commafy(1000000.5678, { digits: 2 }) // '1,000,000.57'\n // 字符串每隔4位用空格分隔\n XEUtils.commafy('6660000000000001', {spaceNumber: 4, separator: ' '}) // '6660 0000 0000 0001'\n // 字符串每隔3位用逗号分割\n XEUtils.commafy('abcdeabcdeabcdeabcde', { spaceNumber: 5, separator: ' ' }) // 'abcde abcde abcde abcde'\n "]},{name:"toNumber",args:"num",title:"转数值",desc:"",params:[],codes:["\n XEUtils.toNumber(123) // 123\n XEUtils.toNumber('12.3') // 12.3\n XEUtils.toNumber('abc') // 0\n "]},{name:"toNumberString",args:"num",title:"数值转字符串,科学计数转字符串",desc:"",params:[],codes:["\n XEUtils.toNumberString(1e-14) // '0.00000000000001'\n XEUtils.toNumberString(1e+22) // '10000000000000000000000'\n "]},{name:"toInteger",args:"num",title:"转整数",desc:"",params:[],codes:["\n XEUtils.toInteger(123) // 123\n XEUtils.toInteger('12.3') // 12\n XEUtils.toInteger('abc') // 0\n "]},{name:"add",args:"num1, num2",title:"加法运算",desc:"",params:[],codes:["\n XEUtils.add(10, 20) // 30\n XEUtils.add(3.84, 4.78) // 8.62\n XEUtils.add(0.4598, 5.024666) // 5.484466\n "]},{name:"subtract",args:"num1, num2",title:"减法运算",desc:"",params:[],codes:["\n XEUtils.subtract(20, 10) // 10\n XEUtils.subtract(6.66, 3.9) // 2.76\n XEUtils.subtract(5.024664, 0.453) // 4.571664\n "]},{name:"multiply",args:"num1, num2",title:"乘法运算",desc:"",params:[],codes:["\n XEUtils.multiply(20, 10) // 200\n XEUtils.multiply(6.66, 3.7) // 24.642\n XEUtils.multiply(5.024664, 0.453) // 2.276172792\n "]},{name:"divide",args:"num1, num2",title:"除法运算",desc:"",params:[],codes:["\n XEUtils.divide(20, 10) // 2\n XEUtils.divide(2.997, 0.9) // 3.33\n XEUtils.divide(182.967, 25.77) // 7.1\n "]}]},{label:"String",value:"string",expand:!0,children:[{name:"toValueString",args:"obj",title:"转字符串",desc:"",params:[],codes:["\n XEUtils.toValueString(0) // '0'\n XEUtils.toValueString(1e-5) // '0.00001'\n XEUtils.toValueString(null) // ''\n XEUtils.toValueString(undefined) // ''\n "]},{name:"trim",args:"str",title:"去除字符串左右两边的空格",desc:"",params:[],codes:["\n XEUtils.trim(' abc ') // 'abc'\n "]},{name:"trimLeft",args:"str",title:"去除字符串左边的空格",desc:"",params:[],codes:["\n XEUtils.trimLeft(' abc ') // 'abc '\n "]},{name:"trimRight",args:"str",title:"去除字符串右边的空格",desc:"",params:[],codes:["\n XEUtils.trimRight(' abc ') // ' abc'\n "]},{name:"escape",args:"str",title:"转义HTML字符串,替换&, <, >, \", ', `字符",desc:"",params:[],codes:["\n XEUtils.escape('link') // '<a>link</a>'\n "]},{name:"unescape",args:"str",title:"反转 escape",desc:"",params:[],codes:["\n XEUtils.unescape('<a>link</a>') // 'link'\n "]},{name:"camelCase",args:"str",title:"将带驼峰字符串转成字符串",desc:"",params:[],codes:["\n XEUtils.camelCase('project-name') // 'projectName'\n "]},{name:"kebabCase",args:"str",title:"将字符串转成驼峰字符串",desc:"",params:[],codes:["\n XEUtils.kebabCase('projectName') // 'project-name'\n "]},{name:"repeat",args:"str, count",title:"将字符串重复 n 次",desc:"",params:[],codes:["\n XEUtils.repeat('a', 5) // 'aaaaa'\n XEUtils.repeat('ab', 3) // 'ababab'\n "]},{name:"padStart",args:"str, targetLength, padString",title:"用指定字符从前面开始补全字符串",desc:"",params:[],codes:["\n XEUtils.padStart('a', 5, 'b') // 'bbbba'\n "]},{name:"padEnd",args:"str, targetLength [, padString]",title:"用指定字符从后面开始补全字符串",desc:"",params:[],codes:["\n XEUtils.padEnd('a', 5, 'b') // 'abbbb'\n "]},{name:"startsWith",args:"str, val [, startIndex]",title:"判断字符串是否在源字符串的头部",desc:"",params:[],codes:["\n XEUtils.startsWith('abc', 'b') // false\n "]},{name:"endsWith",args:"str, val [, startIndex]",title:"判断字符串是否在源字符串的尾部",desc:"",params:[],codes:["\n XEUtils.endsWith('abc', 5, 'a') // false\n "]},{name:"template",args:"str, obj",title:"解析动态字符串模板",desc:"",params:[],codes:["\n XEUtils.template('{{ name }}', {name: 'test1'}) // test1\n XEUtils.template('{{ name }} {{{age}}}', {name: 'test1', age: 26}) // test1 {26}\n "]}]},{label:"Url",value:"url",expand:!0,children:[{name:"parseUrl",args:"url",title:"解析 URL 参数",desc:"",params:[],codes:["\n XEUtils.parseUrl('http://localhost:8080/demo/#/home?id=123')\n // {\n // hash: '#/home?id=123',\n // hashKey: '/home',\n // hashQuery: {\n // id: '123'\n // },\n // host: 'localhost:8080',\n // hostname: 'localhost.com',\n // href: 'http://localhost:8080/demo/#/home?id=123',\n // origin: 'http://localhost:8080',\n // path: '/demo/',\n // pathname: '/demo/',\n // port: '8080',\n // protocol: 'http:',\n // search: '',\n // searchQuery: {}\n // }\n "]},{name:"serialize",args:"query",title:"序列化查询参数",desc:"",params:[],codes:["\n XEUtils.serialize({id: 123, name: 'test1'}) // id=123&name=test1\n "]},{name:"unserialize",args:"str",title:"反转序列化查询参数",desc:"",params:[],codes:["\n XEUtils.unserialize('id=123&name=test1') // {id: '123', name: 'test1'}\n "]}]},{label:"Web",value:"web",expand:!0,children:[{name:"browse",args:"",title:"获取浏览器信息",desc:"",params:[],codes:['\n XEUtils.browse()\n // {\n // "-khtml": false,\n // "-moz": false,\n // "-ms": fasle,\n // "-o": false,\n // "-webkit": true,\n // isMobile: false,\n // isNode: false,\n // isPC: true,\n // isLocalStorage: true,\n // isSessionStorage: true\n // }\n ']},{name:"locat",args:"",title:"获取地址栏信息",desc:"",params:[],codes:["\n // http://localhost:8080/demo?id=123\n XEUtils.locat()\n // {\n // hash: '',\n // hashKey: '',\n // hashQuery: {},\n // host: 'localhost:8080',\n // hostname: 'localhost',\n // href: 'http://localhost:8080/demo?id=123',\n // origin: 'http://localhost:8080',\n // path: '/demo?id=123',\n // pathname: '/demo',\n // port: '8080',\n // protocol: 'http:',\n // search: '?id=123',\n // searchQuery: {\n // id: '123'\n // }\n // }\n "]},{name:"getBaseURL",args:"",title:"获取上下文路径",desc:"",params:[],codes:["\n XEUtils.getBaseURL() // http://localhost/demo/\n "]},{name:"cookie",args:"name, value, options",title:"Cookie 操作函数",desc:"",params:[],codes:["\n // 获取所有\n XEUtils.cookie()\n // 根据name获取\n XEUtils.cookie('name')\n // 删除\n XEUtils.cookie('name', null, {expires: -1})\n XEUtils.cookie('name', null, {expires: -1, path: '/'})\n // 添加/修改\n XEUtils.cookie('name', 'value')\n // 指定 10 秒后过期\n XEUtils.cookie('name', 'value', {expires: '10s'})\n // 指定 1 分钟后过期\n XEUtils.cookie('name', 'value', {expires: '1m'})\n // 指定 1 小时后过期\n XEUtils.cookie('name', 'value', {expires: '1H'})\n // 指定 1 天后过期\n XEUtils.cookie('name', 'value', {expires: '1d'})\n // 指定 1 月后过期\n XEUtils.cookie('name', 'value', {expires: '1M'})\n // 指定 1 年后过期\n XEUtils.cookie('name', 'value', {expires: '1y'})\n // 指定时间戳后过期\n XEUtils.cookie('name', 'value', {expires: 1525541938031})\n // 指定日期过期\n XEUtils.cookie('name', 'value', {expires: new Date()})\n // 指定 UTCString 格式日期\n XEUtils.cookie('name', 'value', {expires: new Date().toUTCString()})\n // 指定数值 1 天后过期\n XEUtils.cookie('name', 'value', {expires: 1})\n // 完整设置domain/path/secure/expires\n XEUtils.cookie('name', 'value', {domain: 'xxx.com', path: '/', expires: 7, secure: true})\n\n // 批量删除\n XEUtils.cookie([{name: 'name', expires: -1}])\n // 批量添加/修改\n XEUtils.cookie([{name: 'name', value: 'value'}])\n // 批量添加并设置domain/path/secure/expires 7天后过期\n XEUtils.cookie([{name: 'name', value: 'value', domain: 'xxx.com', path: '/', expires: 7, secure: true}])\n\n // 判断name是否存在\n XEUtils.cookie.has(name)\n // 添加\n XEUtils.cookie.set(name, value, option)\n XEUtils.cookie.set(name, value, option).set(name, value, option)\n // 根据name获取\n XEUtils.cookie.get(name)\n // 删除\n XEUtils.cookie.remove(name)\n XEUtils.cookie.remove(name, {path: '/'})\n "]}]},{label:"Setting",value:"setup",expand:!0,children:[{name:"setup",args:"options",title:"全局参数设置",desc:"",params:[],codes:["\n XEUtils.setup({\n cookies: {\n path: '/'\n },\n treeOptions: {strict: false, parentKey: 'parentId', key: 'id', children: 'children', data: null},\n formatDate: 'yyyy-MM-dd HH:mm:ss.SSS',\n formatString: 'yyyy-MM-dd HH:mm:ss',\n formatStringMatchs : {\n E: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],\n q: [null, '第一季度', '第二季度', '第三季度', '第四季度']\n },\n commafys: {spaceNumber: 3, separator: ',', fixed: 0}\n })\n "]},{name:"mixin",args:"func",title:"扩展函数,将您自己的实用函数扩展到 XEUtils",desc:"",params:[],codes:["\n XEUtils.mixin({\n toDateDiffText (date) {\n let currDate = 1544407800000 // '2018-12-10 10:10:00'\n let dateDiff = XEUtils.getDateDiff(date, currDate)\n if (dateDiff.done) {\n if (dateDiff.time < 31536000000) {\n if (dateDiff.time < 2592000000) {\n if (dateDiff.time < 86400000) {\n if (dateDiff.time < 360000) {\n if (dateDiff.time < 60000) {\n if (dateDiff.time < 10000) {\n return `刚刚`\n }\n return `${dateDiff.ss}秒之前`\n }\n return `${dateDiff.mm}分钟之前`\n }\n return `${dateDiff.HH}小时之前`\n }\n return `${dateDiff.dd}天之前`\n }\n return `${dateDiff.MM}个月之前`\n }\n return `${dateDiff.yyyy}年之前`\n }\n return '错误类型'\n }\n })\n\n XEUtils.toDateDiffText('2018-12-10 10:09:59') // 刚刚\n XEUtils.toDateDiffText('2018-12-10 10:09:30') // 30秒之前\n XEUtils.toDateDiffText('2018-12-10 10:09:30') // 2分钟之前\n XEUtils.toDateDiffText('2018-12-10 02:10:00') // 8小时之前\n XEUtils.toDateDiffText('2018-12-09 04:09:30') // 1天之前\n XEUtils.toDateDiffText('2018-04-09 04:09:30') // 8个月之前\n XEUtils.toDateDiffText('2016-06-09 04:09:30') // 2年之前\n "]}]}]}},computed:{apiList:function(){if(this.filterName){var e=this.filterName.toLowerCase(),n=new RegExp(e,"gi"),t=window.XEUtils.searchTree(this.list,(function(n){return(n.name||"").toLowerCase().indexOf(e)>-1||(n.title||"").toLowerCase().indexOf(e)>-1}),{children:"children"});return window.XEUtils.eachTree(t,(function(e){e.name=(e.name||"").replace(n,(function(e){return''.concat(e,"")})),e.title=(e.title||"").replace(n,(function(e){return''.concat(e,"")}))}),{children:"children"}),t}return this.list}},watch:{apiList:function(){var e=this;this.$nextTick((function(){e.apiList.length&&(e.selected=e.apiList[0].children[0],Array.from(e.$el.querySelectorAll("pre code")).forEach((function(e){p.a.highlightBlock(e)})))}))}},created:function(){var e=this,n=1;window.XEUtils.eachTree(this.apiList,(function(e){e.id=n++})),this.selected=this.apiList[0].children[0],this.$nextTick((function(){setTimeout((function(){e.$route.query.to&&e.toView(document.getElementById(e.$route.query.to))}),100)}))},mounted:function(){Array.from(this.$el.querySelectorAll("pre code")).forEach((function(e){p.a.highlightBlock(e)}))},methods:{donationEvent:function(){this.toView(document.getElementById("donation"))},menuLinkEvent:function(e){this.selected=e,this.toView(document.getElementById(e.name))},toView:function(e){e&&e.scrollIntoView?e.scrollIntoView():e&&e.scrollIntoViewIfNeeded&&e.scrollIntoViewIfNeeded()}}},U=g,X=(t("7ff7"),Object(l["a"])(U,m,u,!1,null,"708e691e",null)),f=X.exports;a["a"].use(o["a"]);var h=new o["a"]({routes:[{path:"/",name:"API",component:f}]});t("8da8");a["a"].config.productionTip=!1,new a["a"]({router:h,render:function(e){return e(c)}}).$mount("#app")}}); \ No newline at end of file +(function(e){function n(n){for(var a,l,r=n[0],d=n[1],c=n[2],m=0,u=[];m true\n XEUtils.isDate(new Date()) // true\n "]},{name:"isValidDate",args:"val",title:"和 isDate 的区别是同时判断类型与有效日期,如果为无效日期 Invalid Date 则返回 false",desc:"",params:[],codes:["\n XEUtils.isValidDate('2017-12-20') // false\n XEUtils.isValidDate(1514096716800) // false\n XEUtils.isValidDate(new Date('abc')) // Invalid Date => false\n XEUtils.isValidDate(new Date()) // true\n "]},{name:"isError",args:"val",title:"判断是否 Error 对象",desc:"",params:[],codes:["\n XEUtils.isError(null) // false\n XEUtils.isError({}) // false\n XEUtils.isError(new TypeError('error')) // true\n XEUtils.isError(new Error('error')) // true\n "]},{name:"isTypeError",args:"val",title:"判断是否 TypeError 对象",desc:"",params:[],codes:["\n XEUtils.isTypeError(null) // false\n XEUtils.isTypeError({}) // false\n XEUtils.isTypeError(new Error('error')) // false\n XEUtils.isTypeError(new TypeError('error')) // true\n "]},{name:"isEmpty",args:"val",title:"判断是否为空对象",desc:"",params:[],codes:["\n XEUtils.isEmpty([11, 22]) // false\n XEUtils.isEmpty({a:null}) // false\n XEUtils.isEmpty(null) // true\n XEUtils.isEmpty({}) // true\n XEUtils.isEmpty([]) // true\n "]},{name:"isNull",args:"val",title:"判断是否为 Null",desc:"",params:[],codes:["\n XEUtils.isNull(0) // false\n XEUtils.isNull('') // false\n XEUtils.isNull(null) // true\n "]},{name:"isSymbol",args:"val",title:"判断是否 Symbol 对象",desc:"",params:[],codes:["\n XEUtils.isSymbol('a') // false\n XEUtils.isSymbol(Symbol('a')) // true\n "]},{name:"isArguments",args:"val",title:"判断是否 Arguments 对象",desc:"",params:[],codes:["\n XEUtils.isArguments([]) // false\n XEUtils.isArguments(arguments) // true\n "]},{name:"isElement",args:"val",title:"判断是否 Element 对象",desc:"",params:[],codes:["\n XEUtils.isElement({}) // false\n XEUtils.isElement(document.createElement('div')) // true\n "]},{name:"isDocument",args:"val",title:"判断是否 Document 对象",desc:"",params:[],codes:["\n XEUtils.isDocument({}) // false\n XEUtils.isDocument(document.createElement('div')) // false\n XEUtils.isDocument(document) // true\n "]},{name:"isWindow",args:"val",title:"判断是否 Window 对象",desc:"",params:[],codes:["\n XEUtils.isWindow({}) // false\n XEUtils.isWindow(document) // false\n XEUtils.isWindow(window) // true\n "]},{name:"isFormData",args:"val",title:"判断是否 FormData 对象",desc:"",params:[],codes:["\n XEUtils.isFormData({}) // false\n XEUtils.isFormData(new FormData()) // true\n "]},{name:"isMap",args:"val",title:"判断是否 Map 对象",desc:"",params:[],codes:["\n XEUtils.isMap({}) // false\n XEUtils.isMap(new Map()) // true\n "]},{name:"isWeakMap",args:"val",title:"判断是否 WeakMap 对象",desc:"",params:[],codes:["\n XEUtils.isWeakMap({}) // false\n XEUtils.isWeakMap(new WeakMap()) // true\n "]},{name:"isSet",args:"val",title:"判断是否 Set 对象",desc:"",params:[],codes:["\n XEUtils.isSet({}) // false\n XEUtils.isSet(new Set()) // true\n "]},{name:"isWeakSet",args:"val",title:"判断是否 WeakSet 对象",desc:"",params:[],codes:["\n XEUtils.isWeakSet({}) // false\n XEUtils.isWeakSet(new WeakSet()) // true\n "]},{name:"isLeapYear",args:"date",title:"判断是否闰年",desc:"",params:[],codes:["\n XEUtils.isLeapYear(1606752000000) // true\n XEUtils.isLeapYear('2018-12-01') // false\n XEUtils.isLeapYear('2020-12-01') // true\n XEUtils.isLeapYear(new Date('2020/12/01')) // true\n "]},{name:"isMatch",args:"obj, source",title:"判断属性中的键和值是否包含在对象中",desc:"",params:[],codes:["\n XEUtils.isMatch({ aa: 11, bb: 22 }, { bb: 22 }) // true\n XEUtils.isMatch({ aa: 11, bb: 22 }, { bb: 33 }) // false\n "]},{name:"isEqual",args:"obj1, obj2",title:"深度比较两个对象之间的值是否相等",desc:"",params:[],codes:["\n XEUtils.isEqual({}, []) // false\n XEUtils.isEqual({0: 1}, [1]) // false\n XEUtils.isEqual({name: 'test1'}, {name: 'test1'}) // true\n XEUtils.isEqual({name: 'test1', list: [11, /\\d/]}, {name: 'test1', list: [11, /\\d/]}) // true\n XEUtils.isEqual({name: 'test1', list: [11, 33, {a: /\\D/}]}, {name: 'test1', list: [11, 33, {a: /\\d/}]}) // false\n "]},{name:"isEqualWith",args:"obj1, obj2, func",title:"深度比较两个对象之间的值是否相等,使用自定义比较函数",desc:"",params:[],codes:["\n XEUtils.isEqualWith({0: 1}, [1]) // false\n XEUtils.isEqualWith({0: 1}, [1], (v1, v2) => true) // true\n XEUtils.isEqualWith([1], [1]) // true\n XEUtils.isEqualWith([1], [1], (v1, v2) => false) // false\n "]},{name:"isDateSame",args:"date1, date2, format",title:"判断两个日期是否相同",desc:"",params:[],codes:["\n XEUtils.isDateSame('2018-12-01', '2018-12-01') // true\n XEUtils.isDateSame(new Date(), '2018-12-01', 'yyyy') // 判断是否同一年 true\n XEUtils.isDateSame(new Date(), XEUtils.toStringDate('12/30/2018', 'MM/dd/yyyy'), 'MM') // 判断是否同一月 true\n XEUtils.isDateSame(new Date(), new Date(), 'dd') // 判断是否同一日 true\n XEUtils.isDateSame(new Date(), new Date(), 'yyyyMMdd') // 判断是否同年同月同日 true\n "]},{name:"getType",args:"obj",title:"获取对象类型",desc:"",params:[],codes:["\n XEUtils.getType() // 'undefined'\n XEUtils.getType(null) // 'null'\n XEUtils.getType('') // 'string'\n XEUtils.getType(/\\d/) // 'regexp'\n XEUtils.getType(1) // 'number'\n XEUtils.getType([]) // 'array'\n XEUtils.getType({}) // 'object'\n XEUtils.getType(new Error()) // 'error'\n XEUtils.getType(function(){}) // 'function'\n "]},{name:"uniqueId",args:"prefix",title:"获取一个全局唯一标识",desc:"",params:[],codes:["\n XEUtils.uniqueId() // 1\n XEUtils.uniqueId() // 2\n XEUtils.uniqueId('prefix_') // 'prefix_3'\n "]},{name:"getSize",args:"obj",title:"返回对象的长度",desc:"",params:[],codes:["\n XEUtils.getSize('123') // 3\n XEUtils.getSize([1, 3]) // 2\n XEUtils.getSize({a: 2, b: 5}) // 2\n "]},{name:"toStringJSON",args:"str",title:"字符串转 JSON",desc:"",params:[],codes:["\n XEUtils.toStringJSON('{\"a\":1}') // {a: 1}\n XEUtils.toStringJSON('[11,22]') // [11, 22]\n "]},{name:"toJSONString",args:"obj",title:"JSON 转字符串",desc:"",params:[],codes:["\n XEUtils.toJSONString({a: 1}) // '{\"a\":1}'\n XEUtils.toJSONString([11, 22]) // '[11,22]'\n "]},{name:"keys",args:"obj",title:"获取对象所有属性",desc:"",params:[],codes:["\n XEUtils.keys({a: 11}) // ['a']\n "]},{name:"values",args:"obj",title:"获取对象所有值",desc:"",params:[],codes:["\n XEUtils.values({a: 11}) // [11]\n "]},{name:"entries",args:"obj",title:"获取对象所有属性、值",desc:"",params:[],codes:["\n XEUtils.entries({a: 11}) // [['a', 11]]\n XEUtils.entries([11, 22]) // [['0', 11], ['1', 22]]\n "]},{name:"first",args:"obj",title:"获取对象第一个值",desc:"",params:[],codes:["\n XEUtils.first({a: 11, b : 22}) // 11\n XEUtils.first([11, 22]) // 11\n "]},{name:"last",args:"obj",title:"获取对象最后一个值",desc:"",params:[],codes:["\n XEUtils.last({a: 11, b: 22}) // 22\n XEUtils.last([11, 22]) // 22\n "]},{name:"each",args:"obj, iterate [, context]",title:"通用迭代器",desc:"",params:[],codes:["\n XEUtils.each([11, 22, 33], (item, key) => {\n // 通用迭代器,支持遍历任意类型\n })\n "]},{name:"lastEach",args:"obj, iterate [, context]",title:"通用迭代器,从最后开始迭代",desc:"",params:[],codes:["\n XEUtils.lastEach([11, 22, 33], (item, key) => {\n // 通用迭代器,支持遍历任意类型\n })\n "]},{name:"range",args:"start, stop, step",title:"序号列表生成函数",desc:"",params:[],codes:["\n XEUtils.range(0) // []\n XEUtils.range(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n XEUtils.range(-5, 5) // [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]\n XEUtils.range(0, 10, 2) // [0, 2, 4, 6, 8]\n "]}]},{label:"Object",value:"object",expand:!0,children:[{name:"has",args:"obj, property",title:"检查键、路径是否是该对象的属性",desc:"",params:[],codes:["\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, 'a.b') // true\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, 'a.e') // false\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, 'a.d[0]') // true\n XEUtils.has({a: {b: 11, c: 22, d: [33, {f: 66}]}}, 'a.d[1].f') // true\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, ['a', 'd[1]']) // true\n XEUtils.has({a: {b: 11, c: 22, d: [33, 44]}}, ['a', 'd[3]']) // false\n "]},{name:"get",args:"obj, property, defaultValue",title:"获取对象的属性的值,如果值为 undefined,则返回默认值",desc:"",params:[],codes:["\n XEUtils.get({a: {b: 11, c: 22, d: [33, 44]}}, 'a.b') // 11\n XEUtils.get({a: {b: 11, c: 22, d: [33, 44]}}, 'a.e', 'default') // 'default'\n XEUtils.get({a: {b: 11, c: 22, d: [33, 44]}}, 'a.d[0]') // 33\n XEUtils.get({a: {b: 11, c: 22, d: [33, {f: 66}]}}, 'a.d[1].f') // 66\n XEUtils.get({a: {b: 11, c: 22, d: [33, 44]}}, ['a', 'c']) // 22\n "]},{name:"set",args:"obj, property, value",title:"设置对象属性上的值。如果属性不存在则创建它",desc:"",params:[],codes:["\n XEUtils.set({}, 'a.d[0]', 33) // {a: {d: [33]}}\n XEUtils.set({a: {}}, 'a.d[0].f.h', 44) // {a: {d: [{f: {h: 44}}]}}\n XEUtils.set({}, ['a', 'c'], 22) // {a: {c: 22}}\n XEUtils.set({}, ['a', 'd[0]', 'f', 'h'], 44) // {a: {d: [{f: {h: 44}}]}}\n "]},{name:"clear",args:"obj[, defs, assigns]",title:"清空对象; defs如果不传(清空所有属性)、如果传对象(清空并继承)、如果传值(给所有赋值)",desc:"",params:[],codes:["\n let a = [11, 22, 33, 33]\n XEUtils.clear(a) // []\n XEUtils.clear(a, undefined) // [undefined, undefined, undefined, undefined]\n XEUtils.clear(a, null) // [null, null, null, null]\n let b = {b1: 11, b2: 22}\n XEUtils.clear(b) // {}\n XEUtils.clear(b, undefined) // {b1: undefined, b2: undefined}\n XEUtils.clear(b, null) // {b1: null, b2: null}\n "]},{name:"assign",args:"target, ...sources",title:"将一个或多个源对象复制到目标对象中",desc:"",params:[],codes:["\n const obj1 = {a: 0, b: {b1: 11}}\n const obj2 = XEUtils.assign(obj1, {a: 11}, {c: 33})\n // {a: 11, b: {b1: 11}, c: 33}\n\n const obj3 = {a: 0, b: {b1: 11}}\n const obj4 = XEUtils.assign(obj1, {a: 11, b: {b2: 22}})\n // {a: 11, b: {b2: 22}}\n "]},{name:"merge",args:"target, ...sources",title:"将一个或多个源对象合并到目标对象中,和 assign 的区别是会将对象或数组类型递归合并",desc:"",params:[],codes:["\n const obj1 = [{a: 11}, {b: 22}]\n const obj2 = XEUtils.merge(obj1, [{c: 33}, {d: 44}])\n // [{a: 11, c: 33}, {b: 22, d: 44}]\n\n const obj3 = {a: 0, b: {b1: 11}, c: {c1: {d: 44}}}\n const obj4 = XEUtils.merge(obj1, {a: 11, b: {b2: 22}, c: {f1: 55}})\n // {a: 11, b: {b1: 11, b2: 22}, c: {c1: {d: 44}, f1: 55}}\n "]},{name:"clone",args:"obj, deep",title:"浅拷贝/深拷贝,和 assign 的区别是支持对象的递归克隆",desc:"",params:[],codes:["\n let v1 = {a: 11, b: {b1: 22}}\n let v2 = XEUtils.clone(v1)\n if (v1.b === v2.b) {\n // true\n }\n let v3 = XEUtils.clone(v1, true)\n if (v1.b === v3.b) {\n // false\n }\n "]},{name:"destructuring",args:"obj, ...target",title:"将一个或者多个对象值解构到目标对象",desc:"",params:[],codes:["\n XEUtils.destructuring({a: null}, {a: 11, b: 22, c: 33}) // {a: 11}\n XEUtils.destructuring({a: 11, d: 44}, {a: 11, b: 22, c: 33}) // {a: 11, d: 44}\n XEUtils.destructuring({a: 11, c: 33, d: 44}, {a: 11, b: 22, c: null, e: 55, f: 66}) // {a: 11, c: null, d: 44}\n "]},{name:"objectEach",args:"obj, iterate [, context]",title:"对象迭代器",desc:"",params:[],codes:["\n XEUtils.objectEach([11, 22, 33], (item, key) => {\n // 对象迭代器,只能用于遍历对象,性能高于 each\n })\n "]},{name:"lastObjectEach",args:"obj, iterate [, context]",title:"通用迭代器,从最后开始迭代",desc:"",params:[],codes:["\n XEUtils.lastObjectEach([11, 22, 33], (item, key) => {\n // 对象迭代器,只能用于遍历对象,性能高于 lastEach\n })\n "]},{name:"objectMap",args:"obj, iterate [, context]",title:"指定方法后的返回值组成的新对象",desc:"",params:[],codes:["\n XEUtils.objectMap({a: {type: 'a'}, b: {type: 'b'}}, item => item.type) // {a: \"a\", b: \"b\"}\n "]},{name:"pick",args:"obj, array",title:"根据 keys 过滤指定的属性值 或者 接收一个判断函数,返回一个新的对象",desc:"",params:[],codes:["\n XEUtils.pick({name: 'test11', age: 25, height: 176}, 'name', 'height') // {name: 'test11', height: 176}\n XEUtils.pick({name: 'test11', age: 25, height: 176}, ['name', 'age']) // {name: 'test11', age: 25}\n XEUtils.pick({name: 'test11', age: 25, height: 176}, val => XEUtils.isNumber(val)) // {age: 25, height: 176}\n "]},{name:"omit",args:"obj, array",title:"根据 keys 排除指定的属性值 或者 接收一个判断函数,返回一个新的对象",desc:"",params:[],codes:["\n XEUtils.omit({name: 'test11', age: 25, height: 176}, 'name', 'height') // {age: 25}\n XEUtils.omit({name: 'test11', age: 25, height: 176}, ['name', 'age']) // {height: 176}\n XEUtils.omit({name: 'test11', age: 25, height: 176}, val => XEUtils.isNumber(val)) // {name: 'test11'}\n "]}]},{label:"Function",value:"function",expand:!0,children:[{name:"noop",args:"",title:"一个空的方法,始终返回 undefined,可用于初始化值",desc:"",params:[],codes:["\n [11, 22, 33].map(XEUtils.noop)\n // [undefined, undefined, undefined]\n "]},{name:"delay",args:"callback, wait[, ...arguments]",title:"该方法和 setTimeout 一样的效果,区别就是支持额外参数",desc:"",params:[],codes:["\n XEUtils.delay(function (name) {\n console.log(name)\n }, 300, 'test11')\n // 'test11'\n "]},{name:"bind",args:"callback, context[, ...arguments]",title:"创建一个绑定上下文的函数",desc:"",params:[],codes:["\n let rest = XEUtils.bind(function (val) {\n return this.name + ' = ' + val\n }, {name: 'test'})\n rest(222) // 'test = 222'\n rest(333) // 'test = 333'\n "]},{name:"once",args:"callback, context[, ...arguments]",title:"创建一个只能调用一次的函数,只会返回第一次执行后的结果",desc:"",params:[],codes:["\n let rest = XEUtils.once(function (val) {\n return this.name + ' = ' + val\n }, {name: 'test'})\n rest(222) // 'test = 222'\n rest(333) // 'test = 222'\n "]},{name:"after",args:"count, callback, context",title:"创建一个函数, 调用次数超过 count 次之后执行回调并将所有结果记住后返回",desc:"",params:[],codes:["\n function getJSON (url, callback) {\n setTimeout(function() {\n callback({name: 'test1'})\n }, 200)\n }\n\n // 如果你想确保所有异步请求完成之后才执行这个函数\n let finish = XEUtils.after(3, function (rests) {\n console.log('All finish')\n })\n getJSON('/api/list1', finish)\n getJSON('/api/list2', finish)\n getJSON('/api/list3', finish)\n "]},{name:"before",args:"count, callback, context",title:"创建一个函数, 调用次数不超过 count 次之前执行回调并将所有结果记住后返回",desc:"",params:[],codes:["\n document.querySelector('.btn').addEventListener('click', XEUtils.before(4, function (rests) {\n console.log('只能点击三次')\n }))\n "]},{name:"throttle",args:"callback, wait[, options]",title:"节流函数;当被调用 n 毫秒后才会执行,如果在这时间内又被调用则至少每隔 n 秒毫秒调用一次该函数",desc:"",params:[],codes:["\n function scrollEvent (evnt) {\n console.log('至少每隔wait秒毫秒之内只会调用一次')\n }\n\n // 在计时结束之前执行\n document.body.addEventListener('scroll', XEUtils.throttle(scrollEvent, 100))\n // 在计时结束之前执行\n document.body.addEventListener('scroll', XEUtils.throttle(scrollEvent, 100, {\n leading: true,\n trailing: false\n }))\n // 在计时结束之后执行\n document.body.addEventListener('scroll', XEUtils.throttle(scrollEvent, 100, {\n leading: false,\n trailing: true\n }))\n\n let func = XEUtils.throttle(function (msg) {\n console.log(msg)\n }, 300)\n func('执行一次')\n func.cancel()\n func('取消后中断计时,再次调用会马上执行')\n "]},{name:"debounce",args:"callback, wait[, options]",title:"函数去抖;当被调用 n 毫秒后才会执行,如果在这时间内又被调用则将重新计算执行时间",desc:"",params:[],codes:["\n function resizeEvent (evnt) {\n console.log('如果wait毫秒内重复调用则会重新计时,在函数最后一次调用wait毫秒之后才会执行回调')\n }\n\n // 在计时结束之后执行\n document.addEventListener('resize', XEUtils.debounce(resizeEvent, 100))\n // 在计时结束之前执行\n document.addEventListener('resize', XEUtils.debounce(resizeEvent, 100, true))\n // 在计时结束之前执行\n document.addEventListener('resize', XEUtils.debounce(resizeEvent, 100, {\n leading: true,\n trailing: false\n }))\n // 在计时结束之后执行\n document.addEventListener('resize', XEUtils.debounce(resizeEvent, 100, {\n leading: false,\n trailing: true\n }))\n\n let func = XEUtils.debounce(function (msg) {\n console.log(msg)\n }, 300)\n func('计时结束之前执行一次')\n func.cancel()\n func('取消后中重新计时,在计时结束之前执行')\n "]}]},{label:"Array",value:"array",expand:!0,children:[{name:"arrayEach",args:"obj, iterate [, context]",title:"数组迭代器",desc:"",params:[],codes:["\n XEUtils.arrayEach([11, 22, 33], (item, key) => {\n // 数组迭代器,只能用于遍历(数组或伪数组),性能高于 each\n })\n "]},{name:"lastArrayEach",args:"obj, iterate [, context]",title:" 数组迭代器,从最后开始迭代",desc:"",params:[],codes:["\n XEUtils.lastArrayEach([11, 22, 33], (item, key) => {\n // 数组迭代器,只能用于遍历(数组或伪数组),性能高于 lastEach\n })\n "]},{name:"slice",args:"array, start, end",title:"裁剪(数组或伪数组),从 start 位置开始到 end 结束,但不包括 end 本身的位置",desc:"",params:[],codes:["\n XEUtils.slice([11, 22, 33, 44], 1) // [22, 33, 44]\n XEUtils.slice([11, 22, 33, 44], 1, 3) // [22, 33]\n function method () {\n XEUtils.slice(arguments, 1, 3) // [22, 33]\n }\n method(11, 22, 33, 44)\n "]},{name:"indexOf",args:"obj, val",title:"返回对象第一个索引值",desc:"",params:[],codes:["\n XEUtils.indexOf([11, 22, 33, 22], 55) // -1\n XEUtils.indexOf([11, 22, 33, 22], 22) // 1\n "]},{name:"arrayIndexOf",args:"obj, val",title:"返回数组第一个索引值,比 indexOf 快",desc:"",params:[],codes:["\n XEUtils.arrayIndexOf([11, 22, 33, 22], 55) // -1\n XEUtils.arrayIndexOf([11, 22, 33, 22], 22) // 1\n "]},{name:"findIndexOf",args:"obj, iterate [, context]",title:"返回对象第一个索引值",desc:"",params:[],codes:["\n XEUtils.findIndexOf([11, 22, 33, 22], item => item === 55) // -1\n XEUtils.findIndexOf([11, 22, 33, 22], item => item === 22) // 1\n "]},{name:"lastIndexOf",args:"obj, val",title:"从最后开始的索引值,返回对象第一个索引值",desc:"",params:[],codes:["\n XEUtils.lastIndexOf([11, 22, 33, 22], 55) // -1\n XEUtils.lastIndexOf([11, 22, 33, 22], 22) // 3\n "]},{name:"arrayLastIndexOf",args:"obj, val",title:"从最后开始的索引值,返回数组第一个索引值,比 indexOf 快",desc:"",params:[],codes:["\n XEUtils.arrayLastIndexOf([11, 22, 33, 22], 55) // -1\n XEUtils.arrayLastIndexOf([11, 22, 33, 22], 22) // 3\n "]},{name:"findLastIndexOf",args:"obj, iterate [, context]",title:"从最后开始的索引值,返回对象第一个索引值",desc:"",params:[],codes:["\n XEUtils.findLastIndexOf([11, 22, 33, 22], item => item === 55) // -1\n XEUtils.findLastIndexOf([11, 22, 33, 22], item => item === 22) // 3\n "]},{name:"includes",args:"obj, val",title:"判断对象是否包含该值,成功返回 true 否则 false",desc:"",params:[],codes:["\n XEUtils.includes([11], 22) // false\n XEUtils.includes([11, 22], 22) // true\n "]},{name:"includeArrays",args:"array1, array2",title:"判断数组是否包含另一数组",desc:"",params:[],codes:["\n XEUtils.includeArrays([11, 22, 33], []) // true\n XEUtils.includeArrays([11, 22, 33], [11]) // true\n XEUtils.includeArrays([11, 22, 33], [22, 33]) // true\n XEUtils.includeArrays([11, 22, 33], [22, 44]) // false\n "]},{name:"remove",args:"obj, iterate",title:"移除对象属性",desc:"",params:[],codes:["\n let list1 = [11, 22, 33, 44]\n XEUtils.remove(list1, 2) // list1 = [11, 22, 44]\n let list2 = [11, 22, 33, 44]\n XEUtils.remove(list2, item => item === 22) // list2 = [11, 33, 44]\n "]},{name:"orderBy | sortBy",args:"arr, fieldConfs [, context]",title:"将数组进行排序",desc:"",codes:['\n // 数值排序\n XEUtils.orderBy([11, 55, 99, 77, 11, 55, 22])\n // [11,11,22,55,55,77,99]\n XEUtils.orderBy([11, 55, 99, 77, 11, 55, 22], { order: \'desc\' })\n // [99, 77, 55, 55, 22, 11, 11]\n\n // 字母排序\n XEUtils.orderBy([\'x\', \'z\', \'g\', \'q\', \'e\', \'b\', \'a\', \'g\', \'f\', \'c\', \'j\'])\n // ["a","b","c","e","f","g","g","j","q","x","z"]\n\n // 中文排序\n XEUtils.orderBy([\'小\', \'何\', \'李\', \'林\', \'有\', \'好\', \'啊\', \'的\', \'出\', \'库\', \'徐\'])\n // ["啊","出","的","好","何","库","李","林","小","徐","有"]\n\n // 深层对象\n XEUtils.orderBy([{ age: 27 }, { age: 26 }, { age: 28 }], \'age\')\n // [{"age":26},{"age":27},{"age":28}]\n XEUtils.orderBy([{ age: 27 }, { age: 26 }, { age: 28 }], [[\'age\', \'asc\']])\n // [{"age":26},{"age":27},{"age":28}]\n\n // 多字段排序\n XEUtils.orderBy([\n { name: \'x\', age: 26 },\n { name: \'d\', age: 27 },\n { name: \'z\', age: 26 },\n { name: \'z\', age: 24 },\n { name: \'z\', age: 25 }\n ], [[\'age\', \'asc\'], [\'name\', \'desc\']])\n // [{"name":"z","age":24},{"name":"z","age":25},{"name":"z","age":26},{"name":"x","age":26},{"name":"d","age":27}]\n\n // 自定义组合排序\n XEUtils.orderBy([\n { name: \'x\', age: 26 },\n { name: \'d\', age: 27 },\n { name: \'x\', age: 26 },\n { name: \'z\', age: 26 }\n ], [[item => item.name, \'asc\'], [item => item.age, \'desc\']])\n // [{"name":"d","age":27},{"name":"x","age":26},{"name":"x","age":26},{"name":"z","age":26}]\n ']},{name:"shuffle",args:"array",title:"将一个数组随机打乱,返回一个新的数组",desc:"",params:[],codes:["\n XEUtils.shuffle([11, 22, 33, 44, 55]) // [22, 33, 55, 11, 44]\n "]},{name:"sample",args:"array, number",title:"从一个数组中随机返回几个元素",desc:"",params:[],codes:["\n XEUtils.sample([11, 22, 33, 44, 55], 3) // [22, 33, 55]\n "]},{name:"some",args:"obj, iterate [, context]",title:"对象中的值中的每一项运行给定函数,如果函数对任一项返回 true,则返回 true,否则返回 false",desc:"",params:[],codes:["\n XEUtils.some([{value: 11}, {value: 22}], item => item.value === 55) // false\n "]},{name:"every",args:"obj, iterate [, context]",title:" 对象中的值中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true,否则返回 false",desc:"",params:[],codes:["\n XEUtils.every([{value: 11}, {value: 22}], item => item.value === 11) // false\n "]},{name:"filter",args:"obj, iterate [, context]",title:"根据回调过滤数据",desc:"",params:[],codes:["\n XEUtils.filter([{value: 11}, {value: 22}], item => item.value > 11) // [{value: 22}]\n "]},{name:"find",args:"obj, iterate [, context]",title:"查找匹配第一条数据",desc:"",params:[],codes:["\n XEUtils.find([{value: 11}, {value: 22}], item => item.value === 55) // null\n "]},{name:"findKey",args:"obj, iterate [, context]",title:"查找匹配第一条数据的键",desc:"",params:[],codes:["\n XEUtils.findKey([{value: 11}, {value: 22}], item => item.value === 22) // '1'\n XEUtils.findKey({aa: 11, bb: 22, cc: 33}, item => item === 22) // 'bb'\n "]},{name:"map",args:"obj, iterate [, context]",title:"指定方法后的返回值组成的新数组",desc:"",params:[],codes:["\n XEUtils.map([{value: 11}, {value: 22}], item => item.value) // [11, 22]\n "]},{name:"copyWithin",args:"array, target, start [, end]",title:"浅复制数组的一部分到同一数组中的另一个位置,数组大小不变",desc:"",params:[],codes:["\n XEUtils.copyWithin([11, 22, 33, 44], 0, 2) // [33, 44, 33, 44]\n XEUtils.copyWithin([11, 22, 33, 44], 0, -1) // [44, 22, 33, 44]\n "]},{name:"sum",args:"obj, iterate [, context]",title:"求和函数,将数值相加",desc:"",params:[],codes:["\n XEUtils.sum([22, 66, 88]) // 176\n XEUtils.sum([{value: 11}, {value: 22}, {value: 66}], 'value') // 99\n XEUtils.sum({val1: 21, val2: 34, val3: 47}) // 102\n "]},{name:"mean",args:"obj, iterate [, context]",title:" 求平均值函数",desc:"",params:[],codes:["\n XEUtils.mean({ val1: 21, val2: 34, val3: 47 }) // 34\n XEUtils.mean([22, 66, 60, 60]) // 52\n XEUtils.mean([{value: 34}, {value: 22}], 'value') // 28\n XEUtils.mean([{value: 11}, {value: 22}, {value: 66}], item => item.value * 2) // 66\n XEUtils.mean({val1: 21, val2: 34, val3: 45, val4: 55}) // 38.75\n "]},{name:"toArray",args:"array",title:"将对象或者伪数组转为新数组",desc:"",params:[],codes:["\n XEUtils.toArray([]) // []\n XEUtils.toArray({}) // []\n XEUtils.toArray({name: 'test1', age: 25}) // ['test1', 25]\n XEUtils.toArray(arguments) // [...]\n XEUtils.toArray(document.querySelectorAll('div')) // [...]\n "]},{name:"reduce",args:"array, iterate [, initialValue]",title:"接收一个函数作为累加器,数组中的每个值(从左到右)开始合并,最终为一个值",desc:"",params:[],codes:["\n XEUtils.reduce([22, 66, 88], (previous, item) => previous + item) // 176\n "]},{name:"zip",args:"...[]",title:"将每个数组中相应位置的值合并在一起",desc:"",params:[],codes:["\n XEUtils.zip(['name1', 'name2', 'name3'], [true, true, false], [30, 40, 20])\n // [['name1', true, 30], ['name2', true, 40], ['name3', false, 20]]\n "]},{name:"unzip",args:"arrays",title:"与 zip 相反",desc:"",params:[],codes:["\n XEUtils.unzip([['name1', true, 30], ['name2', true, 40], ['name3', false, 20]])\n // [['name1', 'name2', 'name3'], [true, true, false], [30, 40, 20]]\n "]},{name:"zipObject",args:"props, values",title:"根据键数组、值数组对转换为对象",desc:"",params:[],codes:["\n XEUtils.zipObject(['aa', 'bb', 'cc'], [11, 22, 33])\n // { aa: 11, bb: 22, cc: 33 }\n "]},{name:"uniq",args:"array",title:" 数组去重",desc:"",params:[],codes:["\n XEUtils.uniq([11, 22, 33, 33, 22, 55]) // [11, 22, 33, 55]\n "]},{name:"union",args:"...array",title:"将多个数的值返回唯一的并集数组",desc:"",params:[],codes:["\n XEUtils.union([11, 22], [33, 22], [44, 11]) // [11, 22, 33, 44]\n "]},{name:"flatten",args:"array, deep",title:"将一个多维数组拍平",desc:"",params:[],codes:["\n XEUtils.flatten([[1, 2, 3], [4, 5, 6], [7, 8]])\n // [1, 2, 3, 4, 5, 6, 7, 8]\n "]},{name:"chunk",args:"array, size",title:"将一个数组分割成大小的组。如果数组不能被平均分配,那么最后一块将是剩下的元素",desc:"",params:[],codes:["\n XEUtils.chunk(['a', 'b', 'c', 'd'], 2) // [['a', 'b'], ['c', 'd']]\n XEUtils.chunk(['a', 'b', 'c', 'd'], 3) // [['a', 'b', 'c'], ['d']]\n "]},{name:"property",args:"path",title:"返回一个获取对象属性的函数",desc:"",params:[],codes:["\n let getName = XEUtils.property('name')\n getName({name: 'test11', age: 25, height: 176}) // 'test11'\n getName({age: 25, height: 176}) // undefined\n "]},{name:"pluck",args:"array, key",title:"获取数组对象中某属性值,返回一个数组",desc:"",params:[],codes:["\n XEUtils.pluck([{a: 11, b: 22}, {a: 33, b: 44}], 'a') // [11, 33]\n XEUtils.pluck([[11, 22, 33], [44, 55, 66]], 1) // [22, 55]\n "]},{name:"invoke",args:"list, path, ...arguments",title:"在list的每个元素上执行方法,任何传递的额外参数都会在调用方法的时候传递给它",desc:"",params:[],codes:["\n XEUtils.invoke([[3, 1, 6, 7], [3, 2, 1, 8]], 'sort') // [[1, 3, 6, 7], [1, 2, 3, 8]]\n XEUtils.invoke(['123', '456'], 'split') // [['123'], ['456']]\n XEUtils.invoke([123, 456], String.prototype.split, '') // [['1', '2', '3'], ['4', '5', '6']]\n XEUtils.invoke([{a: {b: [2, 0, 1]}}, {a: {b: [2, 1]}}, {a: {b: [4, 8, 1]}}], ['a', 'b', 'sort'])\n // [[0, 1, 2], [1, 2], [1, 4, 8]]\n "]},{name:"groupBy",args:"obj, iterate [, context]",title:"集合分组,默认使用键值分组,如果有 iterate 则使用结果进行分组",desc:"",params:[],codes:["\n XEUtils.groupBy([{type: 'a'}, {type: 'b'}], 'type') // {a: [{type: 'a'}], b: [{type: 'b'}]}\n XEUtils.groupBy([{type: 'a'}, {type: 'a'}, {type: 'b'}], 'type')\n // {a: [{type: 'a'}, {type: 'a'}], b: [{type: 'b'}]}\n "]},{name:"countBy",args:"obj, iterate [, context]",title:"集合分组统计,返回各组中对象的数量统计",desc:"",params:[],codes:["\n XEUtils.countBy([{type: 'a'}, {type: 'b'}], 'type') // {a: 1, b: 1}\n XEUtils.countBy([{type: 'a'}, {type: 'a'}, {type: 'b'}], 'type') // {a: 2, b: 1}\n "]},{name:"toArrayTree",args:"array, options",title:"一个高性能的树结构转换函数,将一个带层级的数据列表转成树结构",desc:"",params:[["属性","描述","默认值"],["strict","是否严格模式,会去掉父子关联不存在数据,当子节点为空时将没有 children 属性","false"],["key","节点键值","id"],["parentKey","父节点键值","parentId"],["children","子节点属性","children"],["mapChildren","子节点映射属性",""],["sortKey","对树节点进行排序属性",""],["reverse","sortKey不为空是有效,默认升序","false"],["data","数据存放属性","null"]],codes:['\n // 默认树结构\n let list1 = [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 3, name: \'333\'},\n {id: 4, parentId: 2, name: \'444\'}\n ]\n XEUtils.toArrayTree(list1)\n /*\n [\n {\n "id":1,\n "name":"111",\n "children":[\n {\n "id":2,\n "parentId":1,\n "name":"222",\n "children":[\n {\n "id":4,\n "parentId":2,\n "name":"444",\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "id":3,\n "name":"333",\n "children":[]\n }\n ]\n */\n\n // 返回带排序的树结构\n let list2 = [\n {id: 1, name: \'111\', seq: 5},\n {id: 2, parentId: 1, name: \'222\', seq: 3},\n {id: 3, name: \'333\', seq: 6},\n {id: 4, parentId: 2, name: \'444\', seq: 2},\n {id: 5, parentId: 1, name: \'555\', seq: 1}\n ]\n XEUtils.toArrayTree(list2, {sortKey: \'seq\'})\n /*\n [\n {\n "id":1,\n "name":"111",\n "seq":5,\n "children":[\n {\n "id":5,\n "parentId":1,\n "name":"555",\n "seq":1,\n "children":[]\n },\n {\n "id":2,\n "parentId":1,\n "name":"222",\n "seq":3,\n "children":[\n {\n "id":4,\n "parentId":2\n ,"name":"444",\n "seq":2,\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "id":3,\n "name":"333",\n "seq":6,\n "children":[]\n }\n ]\n */\n\n // 自定义数据存放属性\n let list3 = [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 3, name: \'333\'},\n {id: 4, parentId: 2, name: \'444\'},\n {id: 5, parentId: 22, name: \'555\'}\n ]\n XEUtils.toArrayTree(list3, {data: \'data\'})\n /*\n [\n {\n "data":{"id":1,"name":"111"},\n "id":1,\n "children":[\n {\n "data":{"id":2,"parentId":1,"name":"222"},\n "id":2,\n "parentId":1,\n "children":[\n {\n "data":{"id":4,"parentId":2,"name":"444"},\n "id":4,\n "parentId":2,\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "data":{"id":3,"name":"333"},\n "id":3,\n "children":[]\n },\n {\n "data":{"id":5,"parentId":22,"name":"555"},\n "id":5,\n "parentId":22,\n "children":[]\n }\n ]\n */\n\n // 如果设置为严格模式,(非父子关联及冗余)的数据会被忽略\n let list4 = [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 3, name: \'333\'},\n {id: 4, parentId: 2, name: \'444\'},\n {id: 5, parentId: 22, name: \'555\'}\n ]\n XEUtils.toArrayTree(list4, {strict: true, parentKey: \'parentId\', key: \'id\', children: \'children\', data: \'data\'})\n /*\n [\n {\n "data":{"id":1,"name":"111"},\n "id":1,\n "children":[\n {\n "data":{"id":2,"parentId":1,"name":"222"},\n "id":2,\n "parentId":1,\n "children":[\n {\n "data":{"id":4,"parentId":2,"name":"444"},\n "id":4,\n "parentId":2,\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "data":{"id":3,"name":"333"},\n "id":3,\n "children":[]\n }\n ]\n */\n ']},{name:"toTreeArray",args:"array, options",title:"将一个树结构转成数组列表",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"],["data","数据存放属性",""],["clear","同时移除子节点属性","false"]],codes:['\n let list1 = [\n {\n "id":1,\n "name":"111",\n "children":[\n {\n "id":2,\n "parentId":1,\n "name":"222",\n "children":[\n {\n "id":4,\n "parentId":2,\n "name":"444",\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "id":3,\n "name":"333",\n "children":[]\n }\n ]\n XEUtils.toTreeArray(list1)\n /*\n [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 4, parentId: 2, name: \'444\'}\n {id: 3, name: \'333\'}\n ]\n */\n\n let list2 = [\n {\n "data":{"id":1,"name":"111"},\n "id":1,\n "children":[\n {\n "data":{"id":2,"parentId":1,"name":"222"},\n "id":2,\n "parentId":1,\n "children":[\n {\n "data":{"id":4,"parentId":2,"name":"444"},\n "id":4,\n "parentId":2,\n "children":[]\n }\n ]\n }\n ]\n },\n {\n "data":{"id":3,"name":"333"},\n "id":3,\n "children":[]\n },\n {\n "data":{"id":5,"parentId":22,"name":"555"},\n "id":5,\n "parentId":22,\n "children":[]\n }\n ]\n XEUtils.toTreeArray(list2, {data: \'data\'})\n /*\n [\n {id: 1, name: \'111\'},\n {id: 2, parentId: 1, name: \'222\'},\n {id: 4, parentId: 2, name: \'444\'},\n {id: 3, name: \'333\'},\n {id: 5, parentId: 22, name: \'555\'}\n ]\n */\n ']},{name:"findTree",args:"obj, iterate[, options, context]",title:"从树结构中查找匹配第一条数据的键、值、路径",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n children: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.findTree(tree1, item => item.id === 20) // { item: {id: 20}, ... }\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.findTree(tree2, item => item.id === 20, { children: 'childs' }) // { item: {id: 20}, ... }\n "]},{name:"eachTree",args:"obj, iterate[, options, context]",title:"从树结构中遍历数据的键、值、路径",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n children: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.eachTree(tree1, item => {\n // ...\n })\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.eachTree(tree2, item => {\n // ...\n }, { children: 'childs' })\n "]},{name:"mapTree",args:"obj, iterate[, options, context]",title:"从树结构中指定方法后的返回值组成的新数组",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"],["mapChildren","将子节点映射到指定的属性",""]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 20 }\n ]\n }, {\n id: 3,\n children: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.mapTree(tree1, item => {\n return {\n id: item.id * 2\n }\n })\n // [\n // { id: 2 },\n // {\n // id: 4,\n // children: [\n // { id: 40 }\n // ]\n // }, {\n // id: 6,\n // children: [\n // { id: 60 }\n // ]\n // }\n // ]\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.mapTree(tree2, item => {\n return {\n id: item.id * 2\n }\n }, {children: 'childs'})\n // [\n // { id: 2 },\n // {\n // id: 4,\n // childs: [\n // { id: 40 }\n // ]\n // },\n // {\n // id: 6,\n // childs: [\n // { id: 60 }\n // ]\n // }\n // ]\n\n var tree3 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.mapTree(tree3, item => {\n return {\n id: item.id * 2\n }\n }, { children: 'childs', mapChildren: 'list' })\n // [\n // { id: 2 },\n // {\n // id: 4,\n // list: [\n // { id: 40 }\n // ]\n // },\n // {\n // id: 6,\n // list: [\n // { id: 60 }\n // ]\n // }\n // ]\n "]},{name:"filterTree",args:"obj, iterate[, options, context]",title:"从树结构中根据回调过滤数据",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n children: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.filterTree(tree1, item => item.id === 1) \n // { id: 1 }\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 20 }\n ]\n },\n {\n id: 3,\n childs: [\n { id: 30 }\n ]\n }\n ]\n XEUtils.filterTree(tree2, item => item.id >= 3, {children: 'childs'}) \n // [\n // {\n // id: 3,\n // childs: [\n // { id: 30 }\n // ]\n // }\n // ]\n "]},{name:"searchTree",args:"obj, iterate[, options, context]",title:"从树结构中根据回调查找数据",desc:"",params:[["属性","描述","默认值"],["children","子节点属性","children"],["mapChildren","将子节点映射到指定的属性",""],["original","是否源对象地址引用(谨慎!源数据将被破坏)","false"]],codes:["\n var tree1 = [\n { id: 1 },\n {\n id: 2,\n children: [\n { id: 0 }\n ]\n },\n {\n id: 3,\n children: [\n {\n id: 30,\n children: [\n { id: 3001 }\n ]\n },\n { id: 31 }\n ]\n }\n ]\n XEUtils.searchTree(tree1, item => item.id === 3)\n // [\n // {\n // id: 3,\n // children: [\n // {\n // id: 30,\n // children: [\n // { id: 3001 }\n // ]\n // },\n // { id: 31 }\n // ]\n // }\n // ]\n\n var tree2 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 0 }\n ]\n },\n {\n id: 3,\n childs: [\n {\n id: 30,\n childs: [\n { id: 3001 }\n ]\n },\n { id: 31 }\n ]\n }\n ]\n XEUtils.searchTree(tree2, item => item.id === 30, { children: 'childs' })\n // [\n // {\n // id: 3,\n // childs: [\n // {\n // id: 30,\n // childs: [\n // { id: 3001 }\n // ]\n // }\n // ]\n // }\n // ]\n\n var tree3 = [\n { id: 1 },\n {\n id: 2,\n childs: [\n { id: 0 }\n ]\n },\n {\n id: 3,\n childs: [\n {\n id: 30,\n childs: [\n { id: 3001 }\n ]\n },\n { id: 31 }\n ]\n }\n ]\n XEUtils.searchTree(tree3, item => item.id === 30, { children: 'childs', mapChildren: 'list' })\n // [\n // {\n // id: 3,\n // childs: [\n // {\n // id: 30,\n // childs: [\n // { id: 3001 }\n // ]\n // },\n // { id: 31 }\n // ]\n // list: [\n // {\n // id: 30,\n // list: [\n // { id: 3001 }\n // ]\n // }\n // ]\n // }\n // ]\n "]}]},{label:"Date",value:"date",expand:!0,children:[{name:"now",args:"",title:"返回当前时间戳",desc:"",params:[],codes:["\n XEUtils.now() // Date.now() 获取当前时间戳 1514096716800\n "]},{name:"timestamp",args:"date[, format]",title:"将日期转为时间戳",desc:"",params:[],codes:["\n XEUtils.timestamp() // XEUtils.now() = Date.now() 获取当前时间戳 1514096716800\n XEUtils.timestamp(new Date()) // 1514096716800\n XEUtils.timestamp('2018-12-01') // 1543593600000\n XEUtils.timestamp('2017/12/20 10:10:30.459', 'yyyy/MM/dd HH:mm:ss.SSS') // 1513735830459\n "]},{name:"toStringDate",args:"str, format",title:"任意格式字符串转为日期",desc:"",params:[["属性","描述"],["yyyy","年份"],["MM","月份"],["dd","日"],["HH","小时"],["mm","分钟"],["ss","秒"],["SSS","毫秒"],["Z","时区"]],codes:["\n XEUtils.toStringDate('12/20/2017')\n // 如果解析错误则返回 new Date('Invalid Date')\n XEUtils.toStringDate('2017-12-20')\n // new Date(2017, 11, 20)\n XEUtils.toStringDate('2017-12-20 10:10:30')\n // new Date(2017, 11, 20, 10, 10, 30)\n XEUtils.toStringDate('2017-12-20 10:10:30.568')\n // new Date(2017, 11, 20, 10, 10, 30, 568)\n XEUtils.toStringDate('2017-12-20 10:10:30.2514766')\n // new Date(2017, 11, 20, 10, 10, 30, 251)\n XEUtils.toStringDate('2017-12-20T10:10:30.738+0800')\n // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('2017-12-20T10:10:30.738+01:00')\n // Wed Dec 20 2017 17:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('2017-12-20T10:10:30.738Z')\n // Wed Dec 20 2017 18:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('12/20/2017', 'MM/dd/yyyy')\n // Wed Dec 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('20171220101030', 'yyyyMMddHHmmss')\n // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('2017/12/20 10:10:30', 'yyyy/MM/dd HH:mm:ss')\n // Wed Dec 20 2017 10:10:00 GMT+0800 (中国标准时间)\n XEUtils.toStringDate('12/20/2017 10:10:30.100', 'MM/dd/yyyy HH:mm:ss.SSS')\n // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间)\n "]},{name:"toDateString",args:"date [, format, options]",title:"日期格式化为任意格式字符串(需要注意如果使用了年的第几周等特殊格式,可能会导致跨年偏移,应该避免和年份同时使用)",desc:"",params:[["属性","描述","备注","值的范围"],["yy","年份","自动截取后两位",""],["yyyy","年份","",""],["M","月份","","1~12"],["MM","月份","自动补0","01~12"],["d","日","","1~31"],["dd","日","自动补0","01~31"],["h","12小时制","","1~12"],["hh","12小时制","自动补0"," 01~12"],["H","24小时制","","0~23"],["HH","24小时制","自动补0","00~23"],["m","分钟","","0~59"],["mm","分钟","自动补0","00~59"],["s","秒","","0~59"],["ss","秒","自动补0","00~59"],["S","毫秒","","0~999"],["SSS","毫秒","自动补0","000~999"],["a","am/pm,小写","","am/pm"],["A","AM/PM,大写","","AM/PM"],["D","年份的第几天","","1~366"],["DDD","年份的第几天","自动补0","001~366"],["e","星期几","","0~6"],["E","星期几","","1~7"],["q","季度","","1~4"],["W","年的第几周","","1~53"],["WW","年的第几周","自动补0",""],["Z","时区值","","[+-]HH:mm"],["ZZ","时区值","","[+-]HHmm"]],codes:["\n XEUtils.toDateString(1483250730000)\n // '2017-01-01 14:05:30'\n XEUtils.toDateString(new Date())\n // '2017-01-01 14:05:30'\n XEUtils.toDateString('2017-01-01 10:05:30', 'MM/dd/yyyy')\n // '01/01/2017'\n XEUtils.toDateString('2017-01-01 10:05:30', 'M/d/yyyy')\n // '1/1/2017'\n XEUtils.toDateString(new Date(), 'yyyyMMddHHmmssSSS')\n // '20170101140530099'\n XEUtils.toDateString(new Date(), 'yyyy-MM-dd HH:mm:ss.SSS')\n // '2017-01-01 14:05:30.099'\n XEUtils.toDateString(new Date(), 'yyyy-MM-dd hh:mm:ss.SSS GMTZ')\n // '2017-01-01 02:05:30.099 GMT+08:00'\n XEUtils.toDateString(new Date(), 'yyyy-MM-dd hh:mm:ss.SSS GMTZZ')\n // '2017-01-01 02:05:30.099 GMT+0800'\n XEUtils.toDateString(new Date(), 'yyyy-M-d h:m:s.S')\n // '2017-1-1 2:5:30.99'\n XEUtils.toDateString(new Date(), 'yyyy年MM月dd日 HH时mm分ss秒S毫秒,星期E 第q季度')\n // '2017年01月01日 14时05分30秒99毫秒,星期0 第1季度'\n XEUtils.toDateString(new Date(), 'yy年M月d日 HH时m分s秒S毫秒,星期E 第q季度')\n // '17年1月1日 14时5分30秒99毫秒,星期0 第1季度'\n XEUtils.toDateString(new Date(), 'yyyy年MM月dd日 hh时mm分ss秒SSS毫秒 ZZ 星期E e 第q季 今年第D天 a A')\n // '2017年01月01日 02时05分30秒099毫秒 +0800 星期0 -1 第1季 今年第1天 pm PM'\n XEUtils.toDateString(new Date(), '[yyyy-MM] yyyy-MM-dd')\n // 'yyyy-MM 2017-01-01'\n "]},{name:"getWhatYear",args:"date, offsetYear [, offsetMonth]",title:"返回前几年或后几年的日期,可以指定年的最初时间(first)、年的最后时间(last)、年的月份(0~11),默认当前",desc:"",params:[],codes:["\n XEUtils.getWhatYear(new Date(), -1) // Mon Nov 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear(1513735830000, -1) // Tue Dec 20 2016 10:10:30 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear('2017-12-20', -1) // Tue Dec 20 2016 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear('2017-12-20', 1) // Thu Dec 20 2018 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear('2017-12-20', 0, 'first') // Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatYear('2017-12-20', 0, 'last') // Sun Dec 31 2017 23:59:59 GMT+0800 (中国标准时间)\n "]},{name:"getWhatMonth",args:"date, offsetMonth [, offsetDay]",title:"返回前几月或后几月的日期,可以指定月初(first)、月末(last)、天数,默认当前",desc:"",params:[],codes:["\n XEUtils.getWhatMonth(new Date(), -1) // Mon Nov 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth(1513735830000, -1) // Mon Nov 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth('2017-12-20', -1) // Mon Nov 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth('2017-12-20', 1) // Sat Jan 20 2018 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth('2017-12-20', -1, 'first') // Wed Nov 01 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatMonth('2017-12-20', 1, 'last') // Wed Jan 31 2018 23:59:59 GMT+0800 (中国标准时间)\n "]},{name:"getWhatWeek",args:"date, offsetWeek [, offsetDay, startDay]",title:"返回前几周或后几周的日期,可以指定星期几(0~6)与周视图的起始天(0~6,默认1),默认当前",desc:"",params:[],codes:["\n XEUtils.getWhatWeek(new Date(), -1) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek(1513735830000, -1) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', -1) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', 1) // Sun Dec 31 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', -1, 5, 1) // Fri Dec 15 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', 0, 0, 0) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatWeek('2017-12-20', 1, 0, 0) // Sun Dec 24 2017 00:00:00 GMT+0800 (中国标准时间)\n "]},{name:"getWhatDay",args:"date, offsetDay [, offsetMode]",title:"返回前几天或后几天的日期,可以指定当天最初时间(first)、当天的最后时间(last)",desc:"",params:[],codes:["\n XEUtils.getWhatDay(new Date(), -1) // Tue Dec 19 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay(1513735830000, -1) // Tue Dec 19 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay('2017-12-20', -1) // Tue Dec 19 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay('2017-12-20', 1) // Tue Dec 21 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay('2017-12-20', 0, 'first') // Wed Dec 20 2017 00:00:00 GMT+0800 (中国标准时间)\n XEUtils.getWhatDay('2017-12-20', 0, 'last') // Wed Dec 20 2017 23:59:59 GMT+0800 (中国标准时间)\n "]},{name:"getDayOfYear",args:"date [, offsetYear]",title:"返回某个年份的天数,可以指定前几个年或后几个年,默认当前",desc:"",params:[],codes:["\n XEUtils.getDayOfYear(new Date()) // 365\n XEUtils.getDayOfYear(1513735830000) // 365\n XEUtils.getDayOfYear('2017-12-20') // 365\n XEUtils.getDayOfYear('2019-12-20', 1) // 366\n XEUtils.getDayOfYear('2020-12-20') // 366\n "]},{name:"getYearDay",args:"date",title:"返回某个年份的第几天",desc:"",params:[],codes:["\n XEUtils.getYearDay(new Date()) // 149\n XEUtils.getYearDay('2017-01-20') // 20\n XEUtils.getYearDay('2018-05-20') // 140\n "]},{name:"getYearWeek",args:"date",title:"返回某个年份的第几周",desc:"",params:[],codes:["\n XEUtils.getYearWeek(new Date()) // 22\n XEUtils.getYearWeek('2017-01-20') // 3\n XEUtils.getYearWeek('2018-05-20') // 20\n "]},{name:"getMonthWeek",args:"date",title:"返回某个月份的第几周",desc:"",params:[],codes:["\n XEUtils.getMonthWeek(new Date()) // 4\n XEUtils.getMonthWeek('2017-01-20') // 3\n XEUtils.getMonthWeek('2018-05-20') // 2\n "]},{name:"getDayOfMonth",args:"date [, month]",title:"返回某个月份的天数,可以指定前几个月或后几个月,默认当前",desc:"",params:[],codes:["\n XEUtils.getDayOfMonth(new Date()) // 31\n XEUtils.getDayOfMonth(1513735830000) // 31\n XEUtils.getDayOfMonth('2017-12-20') // 31\n XEUtils.getDayOfMonth('2017-12-20', -1) // 30\n XEUtils.getDayOfMonth('2017-12-20', 1) // 31\n "]},{name:"getDateDiff",args:"startDate, endDate [, rules]",title:"返回两个日期之间差距,如果结束日期小于开始日期 done 为 fasle",desc:"",params:[],codes:["\n XEUtils.getDateDiff('2017-11-20', '2017-12-21')\n // { done: true, time: 2678400000, yyyy: 0, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, S: 0 }\n XEUtils.getDateDiff('2017-12-20', '2017-12-21')\n // { done: true, time: 86400000, yyyy: 0, MM: 0, dd: 1, HH: 0, mm: 0, ss: 0, S: 0 }\n XEUtils.getDateDiff('2018-01-01', '2017-12-21')\n // { done: false, time: 0 }\n let dateDiff = XEUtils.getDateDiff('2017-12-20 10:10:30', '2017-12-21 10:15:00')\n let content = `${dateDiff.mm}分${dateDiff.ss}秒`\n // '4分30秒'\n "]}]},{label:"Number",value:"number",expand:!0,children:[{name:"random",args:"min, max",title:"获取一个指定范围内随机数",desc:"",params:[],codes:["\n XEUtils.random() // 0 ~ 9\n XEUtils.random(3, 6) // 3 ~ 6\n XEUtils.random(0, 5) // 0 ~ 5\n XEUtils.random(10, 100) // 10 ~ 100\n "]},{name:"min",args:"array [, iterate]",title:"获取最小值",desc:"",params:[],codes:["\n XEUtils.min([22, 66, 77, 11]) // 11\n XEUtils.min([{a: 11}, {a: 44}], 'a') // {a: 11}\n XEUtils.min([{a: 11}, {a: 44}], item => item.a) // {a: 11}\n "]},{name:"max",args:"array [, iterate]",title:"获取最大值",desc:"",params:[],codes:["\n XEUtils.max([22, 66, 77, 11]) // 77\n XEUtils.max([{a: 11}, {a: 44}], 'a') // {a: 44}\n XEUtils.max([{a: 11}, {a: 44}], item => item.a) // {a: 44}\n "]},{name:"round",args:"num, digits",title:"将数值四舍五入",desc:"",params:[],codes:["\n XEUtils.round(123.455, 2) // 123.46\n XEUtils.round(123.452, 2) // 123.45\n "]},{name:"ceil",args:"num, digits",title:"将数值向上舍入",desc:"",params:[],codes:["\n XEUtils.ceil(123.455, 2) // 123.46\n XEUtils.ceil(123.452, 2) // 123.46\n "]},{name:"floor",args:"num, digits",title:"将数值向下舍入",desc:"",params:[],codes:["\n XEUtils.floor(123.455, 2) // 123.45\n XEUtils.floor(123.452, 2) // 123.45\n "]},{name:"toFixed",args:"num, digits",title:"将数值四舍五入,并格式化为字符串",desc:"",params:[],codes:["\n XEUtils.toFixed(123.455, 2) // 123.45\n XEUtils.toFixed(123.452, 2) // 123.45\n XEUtils.toFixed(123.452, 4) // 123.4520\n "]},{name:"commafy",args:"num [, options]",title:"数值千分位分隔符、小数点",desc:"",params:[["属性","描述","类型","版本"],["spaceNumber","分割位数,默认3","number",""],["separator","分隔符,默认","string",""],["digits","只对 number 类型有效,小数位数","number","v2+"],["round","只对 number 类型有效,四舍五入,默认true","boolean","v2.7+"],["ceil","只对 number 类型有效,向上舍入","boolean","v2.7+"],["floor","只对 number 类型有效,向下舍入","boolean","v2.7+"]],codes:["\n // 千分位格式化\n XEUtils.commafy(1000000) // '1,000,000'\n // 格式化金额\n XEUtils.commafy(1000000.5678, { digits: 2 }) // '1,000,000.57'\n // 字符串每隔4位用空格分隔\n XEUtils.commafy('6660000000000001', {spaceNumber: 4, separator: ' '}) // '6660 0000 0000 0001'\n // 字符串每隔3位用逗号分割\n XEUtils.commafy('abcdeabcdeabcdeabcde', { spaceNumber: 5, separator: ' ' }) // 'abcde abcde abcde abcde'\n "]},{name:"toNumber",args:"num",title:"转数值",desc:"",params:[],codes:["\n XEUtils.toNumber(123) // 123\n XEUtils.toNumber('12.3') // 12.3\n XEUtils.toNumber('abc') // 0\n "]},{name:"toNumberString",args:"num",title:"数值转字符串,科学计数转字符串",desc:"",params:[],codes:["\n XEUtils.toNumberString(1e-14) // '0.00000000000001'\n XEUtils.toNumberString(1e+22) // '10000000000000000000000'\n "]},{name:"toInteger",args:"num",title:"转整数",desc:"",params:[],codes:["\n XEUtils.toInteger(123) // 123\n XEUtils.toInteger('12.3') // 12\n XEUtils.toInteger('abc') // 0\n "]},{name:"add",args:"num1, num2",title:"加法运算",desc:"",params:[],codes:["\n XEUtils.add(10, 20) // 30\n XEUtils.add(3.84, 4.78) // 8.62\n XEUtils.add(0.4598, 5.024666) // 5.484466\n "]},{name:"subtract",args:"num1, num2",title:"减法运算",desc:"",params:[],codes:["\n XEUtils.subtract(20, 10) // 10\n XEUtils.subtract(6.66, 3.9) // 2.76\n XEUtils.subtract(5.024664, 0.453) // 4.571664\n "]},{name:"multiply",args:"num1, num2",title:"乘法运算",desc:"",params:[],codes:["\n XEUtils.multiply(20, 10) // 200\n XEUtils.multiply(6.66, 3.7) // 24.642\n XEUtils.multiply(5.024664, 0.453) // 2.276172792\n "]},{name:"divide",args:"num1, num2",title:"除法运算",desc:"",params:[],codes:["\n XEUtils.divide(20, 10) // 2\n XEUtils.divide(2.997, 0.9) // 3.33\n XEUtils.divide(182.967, 25.77) // 7.1\n "]}]},{label:"String",value:"string",expand:!0,children:[{name:"toValueString",args:"obj",title:"转字符串",desc:"",params:[],codes:["\n XEUtils.toValueString(0) // '0'\n XEUtils.toValueString(1e-5) // '0.00001'\n XEUtils.toValueString(null) // ''\n XEUtils.toValueString(undefined) // ''\n "]},{name:"trim",args:"str",title:"去除字符串左右两边的空格",desc:"",params:[],codes:["\n XEUtils.trim(' abc ') // 'abc'\n "]},{name:"trimLeft",args:"str",title:"去除字符串左边的空格",desc:"",params:[],codes:["\n XEUtils.trimLeft(' abc ') // 'abc '\n "]},{name:"trimRight",args:"str",title:"去除字符串右边的空格",desc:"",params:[],codes:["\n XEUtils.trimRight(' abc ') // ' abc'\n "]},{name:"escape",args:"str",title:"转义HTML字符串,替换&, <, >, \", ', `字符",desc:"",params:[],codes:["\n XEUtils.escape('link') // '<a>link</a>'\n "]},{name:"unescape",args:"str",title:"反转 escape",desc:"",params:[],codes:["\n XEUtils.unescape('<a>link</a>') // 'link'\n "]},{name:"camelCase",args:"str",title:"将带驼峰字符串转成字符串",desc:"",params:[],codes:["\n XEUtils.camelCase('project-name') // 'projectName'\n "]},{name:"kebabCase",args:"str",title:"将字符串转成驼峰字符串",desc:"",params:[],codes:["\n XEUtils.kebabCase('projectName') // 'project-name'\n "]},{name:"repeat",args:"str, count",title:"将字符串重复 n 次",desc:"",params:[],codes:["\n XEUtils.repeat('a', 5) // 'aaaaa'\n XEUtils.repeat('ab', 3) // 'ababab'\n "]},{name:"padStart",args:"str, targetLength, padString",title:"用指定字符从前面开始补全字符串",desc:"",params:[],codes:["\n XEUtils.padStart('a', 5, 'b') // 'bbbba'\n "]},{name:"padEnd",args:"str, targetLength [, padString]",title:"用指定字符从后面开始补全字符串",desc:"",params:[],codes:["\n XEUtils.padEnd('a', 5, 'b') // 'abbbb'\n "]},{name:"startsWith",args:"str, val [, startIndex]",title:"判断字符串是否在源字符串的头部",desc:"",params:[],codes:["\n XEUtils.startsWith('abc', 'b') // false\n "]},{name:"endsWith",args:"str, val [, startIndex]",title:"判断字符串是否在源字符串的尾部",desc:"",params:[],codes:["\n XEUtils.endsWith('abc', 5, 'a') // false\n "]},{name:"template",args:"str, obj",title:"解析动态字符串模板",desc:"",params:[],codes:["\n XEUtils.template('{{ name }}', {name: 'test1'}) // test1\n XEUtils.template('{{ name }} {{{age}}}', {name: 'test1', age: 26}) // test1 {26}\n "]}]},{label:"Url",value:"url",expand:!0,children:[{name:"parseUrl",args:"url",title:"解析 URL 参数",desc:"",params:[],codes:["\n XEUtils.parseUrl('http://localhost:8080/demo/#/home?id=123')\n // {\n // hash: '#/home?id=123',\n // hashKey: '/home',\n // hashQuery: {\n // id: '123'\n // },\n // host: 'localhost:8080',\n // hostname: 'localhost.com',\n // href: 'http://localhost:8080/demo/#/home?id=123',\n // origin: 'http://localhost:8080',\n // path: '/demo/',\n // pathname: '/demo/',\n // port: '8080',\n // protocol: 'http:',\n // search: '',\n // searchQuery: {}\n // }\n "]},{name:"serialize",args:"query",title:"序列化查询参数",desc:"",params:[],codes:["\n XEUtils.serialize({id: 123, name: 'test1'}) // id=123&name=test1\n "]},{name:"unserialize",args:"str",title:"反转序列化查询参数",desc:"",params:[],codes:["\n XEUtils.unserialize('id=123&name=test1') // {id: '123', name: 'test1'}\n "]}]},{label:"Web",value:"web",expand:!0,children:[{name:"browse",args:"",title:"获取浏览器信息",desc:"",params:[],codes:['\n XEUtils.browse()\n // {\n // "-khtml": false,\n // "-moz": false,\n // "-ms": fasle,\n // "-o": false,\n // "-webkit": true,\n // isMobile: false,\n // isNode: false,\n // isPC: true,\n // isLocalStorage: true,\n // isSessionStorage: true\n // }\n ']},{name:"locat",args:"",title:"获取地址栏信息",desc:"",params:[],codes:["\n // http://localhost:8080/demo?id=123\n XEUtils.locat()\n // {\n // hash: '',\n // hashKey: '',\n // hashQuery: {},\n // host: 'localhost:8080',\n // hostname: 'localhost',\n // href: 'http://localhost:8080/demo?id=123',\n // origin: 'http://localhost:8080',\n // path: '/demo?id=123',\n // pathname: '/demo',\n // port: '8080',\n // protocol: 'http:',\n // search: '?id=123',\n // searchQuery: {\n // id: '123'\n // }\n // }\n "]},{name:"getBaseURL",args:"",title:"获取上下文路径",desc:"",params:[],codes:["\n XEUtils.getBaseURL() // http://localhost/demo/\n "]},{name:"cookie",args:"name, value, options",title:"Cookie 操作函数",desc:"",params:[],codes:["\n // 获取所有\n XEUtils.cookie()\n // 根据name获取\n XEUtils.cookie('name')\n // 删除\n XEUtils.cookie('name', null, {expires: -1})\n XEUtils.cookie('name', null, {expires: -1, path: '/'})\n // 添加/修改\n XEUtils.cookie('name', 'value')\n // 指定 10 秒后过期\n XEUtils.cookie('name', 'value', {expires: '10s'})\n // 指定 1 分钟后过期\n XEUtils.cookie('name', 'value', {expires: '1m'})\n // 指定 1 小时后过期\n XEUtils.cookie('name', 'value', {expires: '1H'})\n // 指定 1 天后过期\n XEUtils.cookie('name', 'value', {expires: '1d'})\n // 指定 1 月后过期\n XEUtils.cookie('name', 'value', {expires: '1M'})\n // 指定 1 年后过期\n XEUtils.cookie('name', 'value', {expires: '1y'})\n // 指定时间戳后过期\n XEUtils.cookie('name', 'value', {expires: 1525541938031})\n // 指定日期过期\n XEUtils.cookie('name', 'value', {expires: new Date()})\n // 指定 UTCString 格式日期\n XEUtils.cookie('name', 'value', {expires: new Date().toUTCString()})\n // 指定数值 1 天后过期\n XEUtils.cookie('name', 'value', {expires: 1})\n // 完整设置domain/path/secure/expires\n XEUtils.cookie('name', 'value', {domain: 'xxx.com', path: '/', expires: 7, secure: true})\n\n // 批量删除\n XEUtils.cookie([{name: 'name', expires: -1}])\n // 批量添加/修改\n XEUtils.cookie([{name: 'name', value: 'value'}])\n // 批量添加并设置domain/path/secure/expires 7天后过期\n XEUtils.cookie([{name: 'name', value: 'value', domain: 'xxx.com', path: '/', expires: 7, secure: true}])\n\n // 判断name是否存在\n XEUtils.cookie.has(name)\n // 添加\n XEUtils.cookie.set(name, value, option)\n XEUtils.cookie.set(name, value, option).set(name, value, option)\n // 根据name获取\n XEUtils.cookie.get(name)\n // 删除\n XEUtils.cookie.remove(name)\n XEUtils.cookie.remove(name, {path: '/'})\n "]}]},{label:"Setting",value:"setup",expand:!0,children:[{name:"setup",args:"options",title:"全局参数设置",desc:"",params:[],codes:["\n XEUtils.setup({\n cookies: {\n path: '/'\n },\n treeOptions: {\n strict: false,\n parentKey: 'parentId',\n key: 'id',\n children: 'children',\n data: null\n },\n parseDateFormat: 'yyyy-MM-dd HH:mm:ss',\n parseDateRules : {\n q: {\n 1: '1', // 第一季\n 2: '2', // 第二季\n 3: '3', // 第三季\n 4: '4' // 第四季\n },\n E: {\n 0: '7', // 星期天\n 1: '1', // 星期一\n 2: '2', // 星期二\n 3: '3', // 星期三\n 4: '4', // 星期四\n 5: '5', // 星期五\n 6: '6' // 星期六\n }\n },\n commafyOptions: {\n spaceNumber: 3,\n separator: ',',\n fixed: 0\n }\n })\n "]},{name:"mixin",args:"func",title:"扩展函数,将您自己的实用函数扩展到 XEUtils",desc:"",params:[],codes:["\n XEUtils.mixin({\n toDateDiffText (date) {\n let currDate = 1544407800000 // '2018-12-10 10:10:00'\n let dateDiff = XEUtils.getDateDiff(date, currDate)\n if (dateDiff.done) {\n if (dateDiff.time < 31536000000) {\n if (dateDiff.time < 2592000000) {\n if (dateDiff.time < 86400000) {\n if (dateDiff.time < 360000) {\n if (dateDiff.time < 60000) {\n if (dateDiff.time < 10000) {\n return `刚刚`\n }\n return `${dateDiff.ss}秒之前`\n }\n return `${dateDiff.mm}分钟之前`\n }\n return `${dateDiff.HH}小时之前`\n }\n return `${dateDiff.dd}天之前`\n }\n return `${dateDiff.MM}个月之前`\n }\n return `${dateDiff.yyyy}年之前`\n }\n return '错误类型'\n }\n })\n\n XEUtils.toDateDiffText('2018-12-10 10:09:59') // 刚刚\n XEUtils.toDateDiffText('2018-12-10 10:09:30') // 30秒之前\n XEUtils.toDateDiffText('2018-12-10 10:09:30') // 2分钟之前\n XEUtils.toDateDiffText('2018-12-10 02:10:00') // 8小时之前\n XEUtils.toDateDiffText('2018-12-09 04:09:30') // 1天之前\n XEUtils.toDateDiffText('2018-04-09 04:09:30') // 8个月之前\n XEUtils.toDateDiffText('2016-06-09 04:09:30') // 2年之前\n "]}]}]}},computed:{apiList:function(){if(this.filterName){var e=this.filterName.toLowerCase(),n=new RegExp(e,"gi"),t=window.XEUtils.searchTree(this.list,(function(n){return(n.name||"").toLowerCase().indexOf(e)>-1||(n.title||"").toLowerCase().indexOf(e)>-1}),{children:"children"});return window.XEUtils.eachTree(t,(function(e){e.name=(e.name||"").replace(n,(function(e){return''.concat(e,"")})),e.title=(e.title||"").replace(n,(function(e){return''.concat(e,"")}))}),{children:"children"}),t}return this.list}},watch:{apiList:function(){var e=this;this.$nextTick((function(){e.apiList.length&&(e.selected=e.apiList[0].children[0],Array.from(e.$el.querySelectorAll("pre code")).forEach((function(e){p.a.highlightBlock(e)})))}))}},created:function(){var e=this,n=1;window.XEUtils.eachTree(this.apiList,(function(e){e.id=n++})),this.selected=this.apiList[0].children[0],this.$nextTick((function(){setTimeout((function(){e.$route.query.to&&e.toView(document.getElementById(e.$route.query.to))}),100)}))},mounted:function(){Array.from(this.$el.querySelectorAll("pre code")).forEach((function(e){p.a.highlightBlock(e)}))},methods:{donationEvent:function(){this.toView(document.getElementById("donation"))},menuLinkEvent:function(e){this.selected=e,this.toView(document.getElementById(e.name))},toView:function(e){e&&e.scrollIntoView?e.scrollIntoView():e&&e.scrollIntoViewIfNeeded&&e.scrollIntoViewIfNeeded()}}},U=g,X=(t("735e"),Object(l["a"])(U,m,u,!1,null,"07f405e2",null)),f=X.exports;a["a"].use(o["a"]);var h=new o["a"]({routes:[{path:"/",name:"API",component:f}]});t("8da8");a["a"].config.productionTip=!1,new a["a"]({router:h,render:function(e){return e(c)}}).$mount("#app")}}); \ No newline at end of file diff --git a/func/commafy.js b/func/commafy.js index 2c052bb..77a5888 100644 --- a/func/commafy.js +++ b/func/commafy.js @@ -1,3 +1,5 @@ +var setupDefaults = require('./setupDefaults') + var round = require('./round') var ceil = require('./ceil') var floor = require('./floor') @@ -7,6 +9,7 @@ var toValueString = require('./toValueString') var toFixed = require('./toFixed') var toNumberString = require('./toNumberString') +var assign = require('./assign') /** * 千分位分隔符、小数点 @@ -16,7 +19,7 @@ var toNumberString = require('./toNumberString') * @return {String} */ function commafy(num, options) { - var opts = options || {} + var opts = assign({}, setupDefaults.commafyOptions, options) var optDigits = opts.digits var isNum = isNumber(num) var rest, result, isNegative, intStr, floatStr diff --git a/func/getDateDiff.d.ts b/func/getDateDiff.d.ts index 45dadbe..0e7a67a 100644 --- a/func/getDateDiff.d.ts +++ b/func/getDateDiff.d.ts @@ -37,6 +37,11 @@ export interface DateDiffResult { S: number; } +/** + * 例如:[['yyyy', 31536000000], ['MM', 2592000000], ['dd', 86400000], ['HH', 3600000], ['mm', 60000], ['ss', 1000], ['S', 0]] + */ +export type GetDateDiffRules = any[][] + /** * 返回两个日期之间差距,如果结束日期小于开始日期 done 为 fasle * @param startDate 开始日期 @@ -50,7 +55,7 @@ export declare function getDateDiff(startDate: string | Date | number, endDate: * @param endDate 结束日期或当期日期 * @param rules 自定义计算规则 */ -export declare function getDateDiff(startDate: string | Date | number, endDate: string | Date | number, rules?: any[][]): DateDiffResult; +export declare function getDateDiff(startDate: string | Date | number, endDate: string | Date | number, rules?: GetDateDiffRules): DateDiffResult; declare module './ctor' { interface XEUtilsMethods { diff --git a/func/getMonthWeek.d.ts b/func/getMonthWeek.d.ts index 73966d2..d5fd67b 100644 --- a/func/getMonthWeek.d.ts +++ b/func/getMonthWeek.d.ts @@ -1,8 +1,11 @@ +import { FirstDayOfWeek } from './getWhatWeek' + /** * 返回某个月份的第几周 * @param date 字符串/日期/时间戳 + * @param firstDay 周视图的起始天,默认星期一 */ -export declare function getMonthWeek(date: string | Date | number): number; +export declare function getMonthWeek(date: string | Date | number, firstDay?: FirstDayOfWeek): number; declare module './ctor' { interface XEUtilsMethods { diff --git a/func/getMonthWeek.js b/func/getMonthWeek.js index 5b41659..8061ae5 100644 --- a/func/getMonthWeek.js +++ b/func/getMonthWeek.js @@ -1,35 +1,14 @@ -var staticWeekTime = require('./staticWeekTime') -var staticStrFirst = require('./staticStrFirst') - -var helperGetYMDTime = require('./helperGetYMDTime') - -var getWhatMonth = require('./getWhatMonth') -var toStringDate = require('./toStringDate') -var getWhatWeek = require('./getWhatWeek') - -var isValidDate = require('./isValidDate') +var helperCreateGetDateWeek = require('./helperCreateGetDateWeek') /** * 返回某个月的第几周 * * @param {Date} date 日期或数字 + * @param {Number} firstDay 周视图的起始天,默认星期一 * @return {Number} */ -function getMonthWeek (date) { - var monthFirst, monthFirstWeek - var currentDate = toStringDate(date) - if (isValidDate(currentDate)) { - monthFirst = getWhatMonth(currentDate, 0, staticStrFirst) - monthFirstWeek = getWhatWeek(monthFirst, 0, 1) - if (monthFirstWeek < monthFirst) { - monthFirstWeek = getWhatWeek(monthFirst, 1, 1) - } - if (currentDate >= monthFirstWeek) { - return Math.floor((helperGetYMDTime(currentDate) - helperGetYMDTime(monthFirstWeek)) / staticWeekTime) + 1 - } - return getMonthWeek(getWhatWeek(currentDate, 0, 1)) - } - return NaN -} +var getMonthWeek = helperCreateGetDateWeek(function (targetDate) { + return new Date(targetDate.getFullYear(), targetDate.getMonth(), 1) +}) module.exports = getMonthWeek diff --git a/func/getWhatMonth.d.ts b/func/getWhatMonth.d.ts index 2415c3f..df938d9 100644 --- a/func/getWhatMonth.d.ts +++ b/func/getWhatMonth.d.ts @@ -1,15 +1,15 @@ /** * 返回前几月或后几月的日期 * @param date 字符串/日期/时间戳 - * @param offset 月偏移量(默认0)、前几个月、后几个月 + * @param offsetMonth 月偏移量(默认0)、前几个月、后几个月 */ export declare function getWhatMonth(date: string | Date | number, offset: number): Date; /** * 返回前几月或后几月的日期,可以指定月初(first)、月末(last)、天数,默认当前 * @param date 字符串/日期/时间戳 - * @param offset 月偏移量(默认默认当前月)、前几个月、后几个月 - * @param day 获取哪天:月初(first)、月末(last)、指定天数(数值) + * @param offsetMonth 月偏移量(默认默认当前月)、前几个月、后几个月 + * @param offsetDay 获取哪天:月初(first)、月末(last)、指定天数(数值) */ export declare function getWhatMonth(date: string | Date | number, offset: number, day: number | 'first' | 'last'): Date; diff --git a/func/getWhatMonth.js b/func/getWhatMonth.js index 6229c7e..dcb627f 100644 --- a/func/getWhatMonth.js +++ b/func/getWhatMonth.js @@ -14,24 +14,24 @@ var isNumber = require('./isNumber') * 返回前几月或后几月的日期 * * @param {Date} date 日期或数字 - * @param {Number} offset 月(默认当前月)、前几个月、后几个月 - * @param {Number/String} day 获取哪天:月初(first)、月末(last)、指定天数(数值),如果为空,但超过指定月份的天数时,则默认单月最后一天 + * @param {Number} offsetMonth 月(默认当前月)、前几个月、后几个月 + * @param {Number/String} offsetDay 获取哪天:月初(first)、月末(last)、指定天数(数值),如果为空,但超过指定月份的天数时,则默认单月最后一天 * @return {Date} */ -function getWhatMonth (date, offset, day) { - var monthOffset = offset && !isNaN(offset) ? offset : 0 +function getWhatMonth (date, offsetMonth, offsetDay) { + var monthNum = offsetMonth && !isNaN(offsetMonth) ? offsetMonth : 0 date = toStringDate(date) if (isValidDate(date)) { - if (day === staticStrFirst) { - return new Date(helperGetDateFullYear(date), helperGetDateMonth(date) + monthOffset, 1) - } else if (day === staticStrLast) { - return new Date(helperGetDateTime(getWhatMonth(date, monthOffset + 1, staticStrFirst)) - 1) - } else if (isNumber(day)) { - date.setDate(day) + if (offsetDay === staticStrFirst) { + return new Date(helperGetDateFullYear(date), helperGetDateMonth(date) + monthNum, 1) + } else if (offsetDay === staticStrLast) { + return new Date(helperGetDateTime(getWhatMonth(date, monthNum + 1, staticStrFirst)) - 1) + } else if (isNumber(offsetDay)) { + date.setDate(offsetDay) } - if (monthOffset) { + if (monthNum) { var currDate = date.getDate() - date.setMonth(helperGetDateMonth(date) + monthOffset) + date.setMonth(helperGetDateMonth(date) + monthNum) if (currDate !== date.getDate()) { // 当为指定天数,且被跨月了,则默认单月最后一天 date.setDate(1) diff --git a/func/getWhatWeek.d.ts b/func/getWhatWeek.d.ts index d4f71a1..16141c9 100644 --- a/func/getWhatWeek.d.ts +++ b/func/getWhatWeek.d.ts @@ -1,17 +1,20 @@ +export type FirstDayOfWeek = 0 | 1 | 2 | 3 | 4 |5 | 6 + /** * 返回前几周或后几周的日期 * @param date 字符串/日期/时间戳 - * @param offset 周偏移量(默认当前周)、前几周、后几周 + * @param offsetWeek 周偏移量(默认当前周)、前几周、后几周 */ -export declare function getWhatWeek(date: string | Date | number, offset: number): Date; +export declare function getWhatWeek(date: string | Date | number, offsetWeek?: FirstDayOfWeek): Date; /** * 返回前几周或后几周的日期,可以指定星期几(0~6),默认当前 * @param date 字符串/日期/时间戳 - * @param offset 周偏移量(默认当前周)、前几周、后几周 - * @param day 星期天(0)、星期一(1)、星期二(2)、星期三(3)、星期四(4)、星期五(5)、星期六(6) + * @param offsetWeek 获取周偏移量(默认0当前周、前几周、后几周) + * @param offsetDay 获取星期几(星期天0、星期一1、星期二2、星期三3、星期四4、星期五5、星期六6) + * @param firstDay 周视图的起始天,默认星期一 */ -export declare function getWhatWeek(date: string | Date | number, offset: number, day: number): Date; +export declare function getWhatWeek(date: string | Date | number, offsetWeek?: number, offsetDay?: FirstDayOfWeek, firstDay?: FirstDayOfWeek): Date; declare module './ctor' { interface XEUtilsMethods { diff --git a/func/getWhatWeek.js b/func/getWhatWeek.js index 298f63d..563d4f3 100644 --- a/func/getWhatWeek.js +++ b/func/getWhatWeek.js @@ -1,31 +1,53 @@ +var setupDefaults = require('./setupDefaults') + var staticDayTime = require('./staticDayTime') var staticWeekTime = require('./staticWeekTime') -var staticParseInt = require('./staticParseInt') var helperGetDateTime = require('./helperGetDateTime') var toStringDate = require('./toStringDate') var isValidDate = require('./isValidDate') +var isNumber = require('./isNumber') /** * 返回前几周或后几周的星期几 * * @param {Date} date 日期 - * @param {Number} offset 周(默认当前周)、前几周、后几周 - * @param {Number} day 星期天(默认0)、星期一(1)、星期二(2)、星期三(3)、星期四(4)、星期五(5)、星期六(6) + * @param {Number} offsetWeek 周(默认当前周)、前几周、后几周 + * @param {Number} offsetDay 星期天(默认0)、星期一(1)、星期二(2)、星期三(3)、星期四(4)、星期五(5)、星期六(6) + * @param {Number} firstDay 周视图的起始天,默认星期一 * @return {Date} */ -function getWhatWeek (date, offset, day) { - var time, whatDayTime, currentDay, customDay +function getWhatWeek (date, offsetWeek, offsetDay, firstDay) { date = toStringDate(date) if (isValidDate(date)) { - customDay = staticParseInt(/^[0-7]$/.test(day) ? day : date.getDay()) - currentDay = date.getDay() - time = helperGetDateTime(date) - whatDayTime = time + ((customDay === 0 ? 7 : customDay) - (currentDay === 0 ? 7 : currentDay)) * staticDayTime - if (offset && !isNaN(offset)) { - whatDayTime += offset * staticWeekTime + var hasCustomDay = isNumber(offsetDay) + var hasStartDay = isNumber(firstDay) + var whatDayTime = helperGetDateTime(date) + // 如果指定了天或周视图起始天 + if (hasCustomDay || hasStartDay) { + var viewStartDay = hasStartDay ? firstDay : setupDefaults.firstDayOfWeek + var currentDay = date.getDay() + var customDay = hasCustomDay ? offsetDay : currentDay + if (currentDay !== customDay) { + var offsetNum = 0 + if (viewStartDay > currentDay) { + offsetNum = -(7 - viewStartDay + currentDay) + } else if (viewStartDay < currentDay) { + offsetNum = viewStartDay - currentDay + } + if (customDay > viewStartDay) { + whatDayTime += ((customDay === 0 ? 7 : customDay) - viewStartDay + offsetNum) * staticDayTime + } else if (customDay < viewStartDay) { + whatDayTime += (7 - viewStartDay + customDay + offsetNum) * staticDayTime + } else { + whatDayTime += offsetNum * staticDayTime + } + } + } + if (offsetWeek && !isNaN(offsetWeek)) { + whatDayTime += offsetWeek * staticWeekTime } return new Date(whatDayTime) } diff --git a/func/getYearWeek.d.ts b/func/getYearWeek.d.ts index 5655e3d..298033b 100644 --- a/func/getYearWeek.d.ts +++ b/func/getYearWeek.d.ts @@ -1,8 +1,11 @@ +import { FirstDayOfWeek } from './getWhatWeek' + /** * 返回某个年份的第几周 * @param date 字符串/日期/时间戳 + * @param firstDay 从年初的星期几为起始开始周开始算,默认星期一 */ -export declare function getYearWeek(date: string | Date | number): number; +export declare function getYearWeek(date: string | Date | number, firstDay?: FirstDayOfWeek): number; declare module './ctor' { interface XEUtilsMethods { diff --git a/func/getYearWeek.js b/func/getYearWeek.js index ef96d54..8948b3a 100644 --- a/func/getYearWeek.js +++ b/func/getYearWeek.js @@ -1,24 +1,14 @@ -var staticDayTime = require('./staticDayTime') - -var toStringDate = require('./toStringDate') - -var isValidDate = require('./isValidDate') +var helperCreateGetDateWeek = require('./helperCreateGetDateWeek') /** * 返回某个年份的第几周 * * @param {Date} date 日期或数字 + * @param {Number} firstDay 从年初的星期几为起始开始周开始算,默认星期一 * @return {Number} */ -function getYearWeek (date) { - date = toStringDate(date) - if (isValidDate(date)) { - date.setHours(0, 0, 0, 0) - date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7) - var week = new Date(date.getFullYear(), 0, 4) - return Math.round(((date.getTime() - week.getTime()) / staticDayTime + (week.getDay() + 6) % 7 - 3) / 7) + 1 - } - return NaN -} +var getYearWeek = helperCreateGetDateWeek(function (targetDate) { + return new Date(targetDate.getFullYear(), 0, 1) +}) module.exports = getYearWeek diff --git a/func/helperCreateGetDateWeek.js b/func/helperCreateGetDateWeek.js new file mode 100644 index 0000000..8201ae0 --- /dev/null +++ b/func/helperCreateGetDateWeek.js @@ -0,0 +1,31 @@ +var setupDefaults = require('./setupDefaults') + +var staticWeekTime = require('./staticWeekTime') + +var isNumber = require('./isNumber') +var isValidDate = require('./isValidDate') +var getWhatWeek = require('./getWhatWeek') + +var helperGetDateTime = require('./helperGetDateTime') + +function createGetDateMonthWeek (getStartDate) { + return function (date, firstDay) { + var viewStartDay = isNumber(firstDay) ? firstDay : setupDefaults.firstDayOfWeek + var targetDate = getWhatWeek(date, 0, viewStartDay, viewStartDay) + if (isValidDate(targetDate)) { + var targetOffsetDate = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()) + var targerStartDate = getStartDate(targetDate) + var targetFirstDay = targerStartDate.getDay() + if (targetFirstDay > viewStartDay) { + targerStartDate.setDate(7 - targetFirstDay + viewStartDay + 1) + } + if (targetFirstDay < viewStartDay) { + targerStartDate.setDate(viewStartDay - targetFirstDay + 1) + } + return Math.floor((helperGetDateTime(targetOffsetDate) - helperGetDateTime(targerStartDate)) / staticWeekTime + 1) + } + return NaN + } +} + +module.exports = createGetDateMonthWeek diff --git a/func/setupDefaults.d.ts b/func/setupDefaults.d.ts index 7de9b7a..6b29583 100644 --- a/func/setupDefaults.d.ts +++ b/func/setupDefaults.d.ts @@ -1,4 +1,13 @@ +import { CommafyOptions } from "./commafy" +import { GetDateDiffRules } from "./getDateDiff" +import { FirstDayOfWeek } from "./getWhatWeek" +import { ToDateStringFormats } from "./toDateString" + export interface SetupDefaults { + /** + * 默认树的转换配置 + * 用于 toArrayTree()、toTreeArray() + */ treeOptions?: { strict?: boolean; parentKey?: string; @@ -7,8 +16,42 @@ export interface SetupDefaults { data?: string; [key: string]: any; }; + /** + * 默认解析的日期格式 + * 用于 toDateString() + */ + parseDateFormat?: string; + /** + * 默认格式化日期的规则 + * 用于 toDateString() + */ + parseDateRules?: ToDateStringFormats; + /** + * 默认周视图的起始天 + * 用于 getWhatWeek()、getYearWeek()、toDateString() + */ + firstDayOfWeek?: FirstDayOfWeek; + /** + * 默认日期差异规则配置 + * 用于 getDateDiff() + */ + dateDiffRules?: GetDateDiffRules; + /** + * 分隔函数配置 + * 用于 commafy() + */ + commafyOptions?: CommafyOptions; + + /** + * 已被 parseDateRules 替换 + * @deprecated + */ + formatStringMatchs?: any; + /** + * 已被 parseDateFormat 替换 + * @deprecated + */ formatString?: string; - dateDiffRules?: any[][]; [key: string]: any; } diff --git a/func/setupDefaults.js b/func/setupDefaults.js index dbaa180..3e08bb1 100644 --- a/func/setupDefaults.js +++ b/func/setupDefaults.js @@ -9,7 +9,8 @@ var setupDefaults = { key: 'id', children: 'children' }, - formatString: 'yyyy-MM-dd HH:mm:ss', + parseDateFormat: 'yyyy-MM-dd HH:mm:ss', + firstDayOfWeek: 1, dateDiffRules: [ ['yyyy', 31536000000], ['MM', 2592000000], diff --git a/func/toDateString.d.ts b/func/toDateString.d.ts index b865a8f..55f551f 100644 --- a/func/toDateString.d.ts +++ b/func/toDateString.d.ts @@ -1,14 +1,40 @@ +import { FirstDayOfWeek } from "./getWhatWeek" + +export type ToDateStringFormats = { + /** + * 用于格式化季度 + * 例如:[null, '第一季度', '第二季度', '第三季度', '第四季度'] + */ + q?: string[] | { + 1: string + 2: string + 3: string + 4: string + } | ((value: string | number, match: string, date: Date) => string); + /** + * 用于格式化周 + * 例如:['日', '一', '二', '三', '四', '五', '六'] + */ + E?: string[] | { + 0: string + 1: string + 2: string + 3: string + 4: string + 5: string + 6: string + } | ((value: string | number, match: string, date: Date) => string); +} + export interface ToDateStringOptions { + /** + * 默认周视图的起始天 + */ + firstDay?: FirstDayOfWeek; /** * 自定义格式化模板 - * { - * formats: { - * q: ['日', '一', '二', '三', '四', '五', '六'], - * E: function (value, match, date) { return '三' } - * } - * } */ - formats?: any + formats?: ToDateStringFormats } /** diff --git a/func/toDateString.js b/func/toDateString.js index dfc48c8..b3dae79 100644 --- a/func/toDateString.js +++ b/func/toDateString.js @@ -27,9 +27,7 @@ function handleCustomTemplate (date, formats, match, value) { return value } -function formatDayE (day) { - return day === 0 ? 7 : day -} +var dateFormatRE = /\[([^\]]+)]|y{2,4}|M{1,2}|d{1,2}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|S{1,3}|Z{1,2}|W{1,2}|D{1,3}|[aAeEq]/g /** * 日期格式化为字符串,转义符号 [] @@ -39,15 +37,14 @@ function formatDayE (day) { * @param {Object} options {formats: {q: ['日', '一', '二', '三', '四', '五', '六'], E: function (value, match, date) {return '三'}, }} 自定义格式化模板 * @return {String} */ -var dateFormatRE = /\[([^\]]+)]|y{2,4}|M{1,2}|d{1,2}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|S{1,3}|Z{1,2}|W{1,2}|D{1,3}|[aAeEq]/g function toDateString (date, format, options) { if (date) { date = toStringDate(date) if (isValidDate(date)) { - var result = format || setupDefaults.formatString + var result = format || setupDefaults.parseDateFormat || setupDefaults.formatString var hours = date.getHours() var apm = hours < 12 ? 'am' : 'pm' - var formats = assign({}, setupDefaults.formatStringMatchs, options ? options.formats : null) + var formats = assign({}, setupDefaults.parseDateRules || setupDefaults.formatStringMatchs, options ? options.formats : null) var fy = function (match, length) { return ('' + helperGetDateFullYear(date)).substr(4 - length) } @@ -77,7 +74,7 @@ function toDateString (date, format, options) { return handleCustomTemplate(date, formats, match, (zoneHours >= 0 ? '+' : '-') + padStart(zoneHours, 2, '0') + (length === 1 ? ':' : '') + '00') } var fW = function (match, length) { - return padStart(handleCustomTemplate(date, formats, match, getYearWeek(date)), length, '0') + return padStart(handleCustomTemplate(date, formats, match, getYearWeek(date, (options ? options.firstDay : null) || setupDefaults.firstDayOfWeek)), length, '0') } var fD = function (match, length) { return padStart(handleCustomTemplate(date, formats, match, getYearDay(date)), length, '0') @@ -115,7 +112,7 @@ function toDateString (date, format, options) { return handleCustomTemplate(date, formats, match, date.getDay()) }, E: function (match) { - return handleCustomTemplate(date, formats, match, formatDayE(date.getDay())) + return handleCustomTemplate(date, formats, match, date.getDay()) }, q: function (match) { return handleCustomTemplate(date, formats, match, Math.floor((helperGetDateMonth(date) + 3) / 3)) diff --git a/func/toStringDate.js b/func/toStringDate.js index e79711a..fcad84b 100644 --- a/func/toStringDate.js +++ b/func/toStringDate.js @@ -23,15 +23,15 @@ function toParseNum (num) { return isNaN(num) ? num : staticParseInt(num) } -var d2 = getParseRule('2') +var d2 = getParseRule(2) var d1or2 = getParseRule('1,2') -var d1or3 = getParseRule('1,3') +var d1or7 = getParseRule('1,7') var d3or4 = getParseRule('3,4') var place = '.{1}' var d1Or2RE = place + d1or2 var dzZ = '(([zZ])|([-+]\\d{2}:?\\d{2}))' -var defaulParseStrs = [d3or4, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, place + d1or3, dzZ] +var defaulParseStrs = [d3or4, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, place + d1or7, dzZ] var defaulParseREs = [] for (var len = defaulParseStrs.length - 1; len >= 0; len--) { @@ -77,8 +77,8 @@ var customParseStrs = [ ['m', d1or2], ['ss', d2], ['s', d1or2], - ['SSS', getParseRule('3')], - ['S', d1or3], + ['SSS', getParseRule(3)], + ['S', d1or7], ['Z', dzZ] ] var parseRuleMaps = {} @@ -163,7 +163,8 @@ function toStringDate (str, format) { resMaps.M = toParseNum(resMaps.M) - 1 } if (resMaps.S) { - resMaps.S = toParseMs(toParseNum(resMaps.S)) + // 如果7位则是微秒,只精确到3位毫秒 + resMaps.S = toParseMs(toParseNum(resMaps.S.substring(0, 3))) } if (resMaps.Z) { return parseTimeZone(resMaps) diff --git a/package.json b/package.json index ef30faa..05db904 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xe-utils", - "version": "3.4.3", + "version": "3.5.0", "description": "JavaScript 函数库、工具类", "main": "index.js", "unpkg": "dist/xe-utils.umd.min.js", diff --git a/src/views/API.vue b/src/views/API.vue index 98553ce..97da15b 100644 --- a/src/views/API.vue +++ b/src/views/API.vue @@ -2399,11 +2399,15 @@ export default { codes: [ ` XEUtils.toStringDate('12/20/2017') - // 如果解析错误则返回 'Invalid Date' + // 如果解析错误则返回 new Date('Invalid Date') XEUtils.toStringDate('2017-12-20') - // Wed Dec 20 2017 00:00:00 GMT+0800 (中国标准时间) + // new Date(2017, 11, 20) XEUtils.toStringDate('2017-12-20 10:10:30') - // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间) + // new Date(2017, 11, 20, 10, 10, 30) + XEUtils.toStringDate('2017-12-20 10:10:30.568') + // new Date(2017, 11, 20, 10, 10, 30, 568) + XEUtils.toStringDate('2017-12-20 10:10:30.2514766') + // new Date(2017, 11, 20, 10, 10, 30, 251) XEUtils.toStringDate('2017-12-20T10:10:30.738+0800') // Wed Dec 20 2017 10:10:30 GMT+0800 (中国标准时间) XEUtils.toStringDate('2017-12-20T10:10:30.738+01:00') @@ -2424,7 +2428,7 @@ export default { { name: 'toDateString', args: 'date [, format, options]', - title: '日期格式化为任意格式字符串', + title: '日期格式化为任意格式字符串(需要注意如果使用了年的第几周等特殊格式,可能会导致跨年偏移,应该避免和年份同时使用)', desc: '', params: [ ['属性', '描述', '备注', '值的范围'], @@ -2489,7 +2493,7 @@ export default { }, { name: 'getWhatYear', - args: 'date, year [, month]', + args: 'date, offsetYear [, offsetMonth]', title: '返回前几年或后几年的日期,可以指定年的最初时间(first)、年的最后时间(last)、年的月份(0~11),默认当前', desc: '', params: [], @@ -2506,7 +2510,7 @@ export default { }, { name: 'getWhatMonth', - args: 'date, month [, day]', + args: 'date, offsetMonth [, offsetDay]', title: '返回前几月或后几月的日期,可以指定月初(first)、月末(last)、天数,默认当前', desc: '', params: [], @@ -2523,8 +2527,8 @@ export default { }, { name: 'getWhatWeek', - args: 'date, week [, day]', - title: '返回前几周或后几周的日期,可以指定星期几(0~6),默认当前', + args: 'date, offsetWeek [, offsetDay, startDay]', + title: '返回前几周或后几周的日期,可以指定星期几(0~6)与周视图的起始天(0~6,默认1),默认当前', desc: '', params: [], codes: [ @@ -2533,14 +2537,15 @@ export default { XEUtils.getWhatWeek(1513735830000, -1) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间) XEUtils.getWhatWeek('2017-12-20', -1) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间) XEUtils.getWhatWeek('2017-12-20', 1) // Sun Dec 31 2017 00:00:00 GMT+0800 (中国标准时间) - XEUtils.getWhatWeek('2017-12-20', -1, 5) // Fri Dec 15 2017 00:00:00 GMT+0800 (中国标准时间) - XEUtils.getWhatWeek('2017-12-20', 1, 0) // Sun Dec 31 2017 00:00:00 GMT+0800 (中国标准时间) + XEUtils.getWhatWeek('2017-12-20', -1, 5, 1) // Fri Dec 15 2017 00:00:00 GMT+0800 (中国标准时间) + XEUtils.getWhatWeek('2017-12-20', 0, 0, 0) // Sun Dec 17 2017 00:00:00 GMT+0800 (中国标准时间) + XEUtils.getWhatWeek('2017-12-20', 1, 0, 0) // Sun Dec 24 2017 00:00:00 GMT+0800 (中国标准时间) ` ] }, { name: 'getWhatDay', - args: 'date, day [, mode]', + args: 'date, offsetDay [, offsetMode]', title: '返回前几天或后几天的日期,可以指定当天最初时间(first)、当天的最后时间(last)', desc: '', params: [], @@ -2557,7 +2562,7 @@ export default { }, { name: 'getDayOfYear', - args: 'date [, year]', + args: 'date [, offsetYear]', title: '返回某个年份的天数,可以指定前几个年或后几个年,默认当前', desc: '', params: [], @@ -3269,14 +3274,36 @@ export default { cookies: { path: '/' }, - treeOptions: {strict: false, parentKey: 'parentId', key: 'id', children: 'children', data: null}, - formatDate: 'yyyy-MM-dd HH:mm:ss.SSS', - formatString: 'yyyy-MM-dd HH:mm:ss', - formatStringMatchs : { - E: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], - q: [null, '第一季度', '第二季度', '第三季度', '第四季度'] + treeOptions: { + strict: false, + parentKey: 'parentId', + key: 'id', + children: 'children', + data: null }, - commafys: {spaceNumber: 3, separator: ',', fixed: 0} + parseDateFormat: 'yyyy-MM-dd HH:mm:ss', + parseDateRules : { + q: { + 1: '1', // 第一季 + 2: '2', // 第二季 + 3: '3', // 第三季 + 4: '4' // 第四季 + }, + E: { + 0: '7', // 星期天 + 1: '1', // 星期一 + 2: '2', // 星期二 + 3: '3', // 星期三 + 4: '4', // 星期四 + 5: '5', // 星期五 + 6: '6' // 星期六 + } + }, + commafyOptions: { + spaceNumber: 3, + separator: ',', + fixed: 0 + } }) ` ] diff --git a/test/date.test.js b/test/date.test.js index d34dae7..ef9da78 100644 --- a/test/date.test.js +++ b/test/date.test.js @@ -277,6 +277,12 @@ describe('Date functions', () => { expect( XEUtils.toStringDate('2017-12-20 10:10:30.999') ).toEqual(new Date(2017, 11, 20, 10, 10, 30, 999)) + expect( + XEUtils.toStringDate('2017-12-20 10:10:30.2880929') + ).toEqual(new Date(2017, 11, 20, 10, 10, 30, 288)) + expect( + XEUtils.toStringDate('2017-12-20 10:10:30.9999999') + ).toEqual(new Date(2017, 11, 20, 10, 10, 30, 999)) expect( XEUtils.toStringDate('2017-12-20T10:10:30.4+0800') ).toEqual(new Date('2017-12-20T10:10:30.400+08:00')) @@ -495,13 +501,13 @@ describe('Date functions', () => { ).toEqual('2017-1-2 2:5:30.99 1 1') expect( XEUtils.toDateString(time, 'yyyy年MM月dd日 HH时mm分ss秒S毫秒,星期E 第q季度') - ).toEqual('2017年01月01日 14时05分30秒99毫秒,星期7 第1季度') + ).toEqual('2017年01月01日 14时05分30秒99毫秒,星期0 第1季度') expect( XEUtils.toDateString(time, 'yy年M月d日 HH时m分s秒S毫秒,星期E 第q季度 今年第D天 今年第W周') - ).toEqual('17年1月1日 14时5分30秒99毫秒,星期7 第1季度 今年第1天 今年第52周') + ).toEqual('17年1月1日 14时5分30秒99毫秒,星期0 第1季度 今年第1天 今年第52周') expect( XEUtils.toDateString(time, 'yyyy年MM月dd日 hh时mm分ss秒SSS毫秒 星期E e 第q季 今年第DDD天 今年第WW周 a A') - ).toEqual('2017年01月01日 02时05分30秒099毫秒 星期7 0 第1季 今年第001天 今年第52周 pm PM') + ).toEqual('2017年01月01日 02时05分30秒099毫秒 星期0 0 第1季 今年第001天 今年第52周 pm PM') expect( XEUtils.toDateString(date, 'yyyy-MM-dd [yyyy-MM-dd] [yyyy]] [[MM]') ).toEqual('2017-01-01 yyyy-MM-dd yyyy] [MM') @@ -826,6 +832,358 @@ describe('Date functions', () => { expect( XEUtils.getWhatWeek('2017-12-20', 1, 0) ).toEqual(new Date(2017, 11, 31)) + + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 0, 0) + ).toEqual(new Date(2017, 10, 26)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 0, 0) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 0, 0) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 0, 0) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 0, 0) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 0, 0) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 0, 0) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 0, 0) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 2, 0) + ).toEqual(new Date(2017, 10, 28)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 2, 0) + ).toEqual(new Date(2017, 11, 19)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 2, 0) + ).toEqual(new Date(2017, 11, 19)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 2, 0) + ).toEqual(new Date(2017, 11, 19)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 2, 0) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 2, 0) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 2, 0) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 2, 0) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-31', 0, 2, 0) + ).toEqual(new Date(2018, 0, 2)) + + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 0, 1) + ).toEqual(new Date(2017, 11, 3)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 0, 1) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 0, 1) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 0, 1) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 0, 1) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 0, 1) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 0, 1) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 0, 1) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 3, 1) + ).toEqual(new Date(2017, 10, 29)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 3, 1) + ).toEqual(new Date(2017, 11, 20)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 3, 1) + ).toEqual(new Date(2017, 11, 20)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 3, 1) + ).toEqual(new Date(2017, 11, 20)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 3, 1) + ).toEqual(new Date(2017, 11, 20)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 3, 1) + ).toEqual(new Date(2017, 11, 27)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 3, 1) + ).toEqual(new Date(2017, 11, 27)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 3, 1) + ).toEqual(new Date(2017, 11, 27)) + + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 0, 2) + ).toEqual(new Date(2017, 11, 3)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 0, 2) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 0, 2) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 0, 2) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 0, 2) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 0, 2) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 0, 2) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 0, 2) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 4, 2) + ).toEqual(new Date(2017, 10, 30)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 4, 2) + ).toEqual(new Date(2017, 11, 14)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 4, 2) + ).toEqual(new Date(2017, 11, 21)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 4, 2) + ).toEqual(new Date(2017, 11, 21)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 4, 2) + ).toEqual(new Date(2017, 11, 21)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 4, 2) + ).toEqual(new Date(2017, 11, 28)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 4, 2) + ).toEqual(new Date(2017, 11, 28)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 4, 2) + ).toEqual(new Date(2017, 11, 28)) + + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 0, 3) + ).toEqual(new Date(2017, 11, 3)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 0, 3) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 0, 3) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 0, 3) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 0, 3) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 0, 3) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 0, 3) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 0, 3) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 6, 3) + ).toEqual(new Date(2017, 11, 2)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 6, 3) + ).toEqual(new Date(2017, 11, 16)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 6, 3) + ).toEqual(new Date(2017, 11, 16)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 6, 3) + ).toEqual(new Date(2017, 11, 23)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 6, 3) + ).toEqual(new Date(2017, 11, 23)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 6, 3) + ).toEqual(new Date(2017, 11, 23)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 6, 3) + ).toEqual(new Date(2017, 11, 30)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 6, 3) + ).toEqual(new Date(2017, 11, 30)) + + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 0, 4) + ).toEqual(new Date(2017, 11, 3)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 0, 4) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 0, 4) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 0, 4) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 0, 4) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 0, 4) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 0, 4) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 0, 4) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 2, 4) + ).toEqual(new Date(2017, 11, 5)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 2, 4) + ).toEqual(new Date(2017, 11, 19)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 2, 4) + ).toEqual(new Date(2017, 11, 19)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 2, 4) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 2, 4) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 2, 4) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 2, 4) + ).toEqual(new Date(2018, 0, 2)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 2, 4) + ).toEqual(new Date(2018, 0, 2)) + + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 0, 5) + ).toEqual(new Date(2017, 11, 3)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 0, 5) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 0, 5) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 0, 5) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 0, 5) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 0, 5) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 0, 5) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 0, 5) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 6, 5) + ).toEqual(new Date(2017, 11, 2)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 6, 5) + ).toEqual(new Date(2017, 11, 16)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 6, 5) + ).toEqual(new Date(2017, 11, 16)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 6, 5) + ).toEqual(new Date(2017, 11, 23)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 6, 5) + ).toEqual(new Date(2017, 11, 23)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 6, 5) + ).toEqual(new Date(2017, 11, 23)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 6, 5) + ).toEqual(new Date(2017, 11, 30)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 6, 5) + ).toEqual(new Date(2017, 11, 30)) + + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 0, 6) + ).toEqual(new Date(2017, 10, 26)) + expect( + XEUtils.getWhatWeek('2017-12-15', 0, 0, 6) + ).toEqual(new Date(2017, 11, 10)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 0, 6) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 0, 6) + ).toEqual(new Date(2017, 11, 17)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 0, 6) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 0, 6) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 0, 6) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 0, 6) + ).toEqual(new Date(2017, 11, 24)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 0, 6) + ).toEqual(new Date(2017, 11, 31)) + expect( + XEUtils.getWhatWeek('2017-12-01', 0, 2, 6) + ).toEqual(new Date(2017, 10, 28)) + expect( + XEUtils.getWhatWeek('2017-12-15', 0, 2, 6) + ).toEqual(new Date(2017, 11, 12)) + expect( + XEUtils.getWhatWeek('2017-12-18', 0, 2, 6) + ).toEqual(new Date(2017, 11, 19)) + expect( + XEUtils.getWhatWeek('2017-12-19', 0, 2, 6) + ).toEqual(new Date(2017, 11, 19)) + expect( + XEUtils.getWhatWeek('2017-12-23', 0, 2, 6) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-24', 0, 2, 6) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-26', 0, 2, 6) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-29', 0, 2, 6) + ).toEqual(new Date(2017, 11, 26)) + expect( + XEUtils.getWhatWeek('2017-12-30', 0, 2, 6) + ).toEqual(new Date(2018, 0, 2)) }) test('getWhatDay()', () => { @@ -1009,6 +1367,27 @@ describe('Date functions', () => { expect( XEUtils.getYearWeek('2018-12-20') ).toEqual(51) + expect( + XEUtils.getYearWeek('2013-01-01', 1) + ).toEqual(53) + expect( + XEUtils.getYearWeek('2013-01-07', 1) + ).toEqual(1) + expect( + XEUtils.getYearWeek('2013-01-27', 1) + ).toEqual(3) + expect( + XEUtils.getYearWeek('2021-01-01', 1) + ).toEqual(52) + expect( + XEUtils.getYearWeek('2021-01-10', 1) + ).toEqual(1) + expect( + XEUtils.getYearWeek('2021-01-31', 1) + ).toEqual(4) + expect( + XEUtils.getYearWeek('2021-12-08', 1) + ).toEqual(49) }) test('getMonthWeek()', () => { @@ -1075,6 +1454,202 @@ describe('Date functions', () => { expect( XEUtils.getMonthWeek('2018-05-29') ).toEqual(4) + + expect( + XEUtils.getMonthWeek('2018-05-01', 0) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-05-28', 0) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-29', 0) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-30', 0) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-31', 0) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-01', 0) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-02', 0) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-03', 0) + ).toEqual(1) + expect( + XEUtils.getMonthWeek('2018-06-04', 0) + ).toEqual(1) + + expect( + XEUtils.getMonthWeek('2018-05-01', 1) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-05-28', 1) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-29', 1) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-30', 1) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-31', 1) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-01', 1) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-02', 1) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-03', 1) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-04', 1) + ).toEqual(1) + + expect( + XEUtils.getMonthWeek('2018-05-01', 2) + ).toEqual(1) + expect( + XEUtils.getMonthWeek('2018-05-28', 2) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-29', 2) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-05-30', 2) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-05-31', 2) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-01', 2) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-02', 2) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-03', 2) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-04', 2) + ).toEqual(5) + + expect( + XEUtils.getMonthWeek('2018-05-01', 3) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-28', 3) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-29', 3) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-30', 3) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-05-31', 3) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-01', 3) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-02', 3) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-03', 3) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-04', 3) + ).toEqual(5) + + expect( + XEUtils.getMonthWeek('2018-05-01', 4) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-28', 4) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-29', 4) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-30', 4) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-31', 4) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-01', 4) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-02', 4) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-03', 4) + ).toEqual(5) + expect( + XEUtils.getMonthWeek('2018-06-04', 4) + ).toEqual(5) + + expect( + XEUtils.getMonthWeek('2018-05-01', 5) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-28', 5) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-29', 5) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-30', 5) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-31', 5) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-01', 5) + ).toEqual(1) + expect( + XEUtils.getMonthWeek('2018-06-02', 5) + ).toEqual(1) + expect( + XEUtils.getMonthWeek('2018-06-03', 5) + ).toEqual(1) + expect( + XEUtils.getMonthWeek('2018-06-04', 5) + ).toEqual(1) + + expect( + XEUtils.getMonthWeek('2018-05-01', 6) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-28', 6) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-29', 6) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-30', 6) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-05-31', 6) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-01', 6) + ).toEqual(4) + expect( + XEUtils.getMonthWeek('2018-06-02', 6) + ).toEqual(1) + expect( + XEUtils.getMonthWeek('2018-06-03', 6) + ).toEqual(1) + expect( + XEUtils.getMonthWeek('2018-06-04', 6) + ).toEqual(1) }) test('getDayOfYear()', () => {