FuncLib

funclib.js

funclib.js 是一个简单、易用、贴进业务逻辑的JavaScript UMD函数库,以高效完成业务代码为目标,具有“通用、实用、易用、好用”等特点!类似于 underscorelodash。 跟它们对比,funclib.js省去了很多js自带的或者不常用的方法,并且改进和拓展了很多方法的使用方式。

funclib.js还根据一些实际业务的逻辑的规律封装了很多前后端都实用的新方法, 让你提高代码质量和交付效率的同时,享受编程的乐趣!

funclib.js使用 Karma / Mocha 进行自动化单元测试, 使用 Travis-CI 进行持续集成。

npm LICENSE MIT Coverage Status Build Status

如果你喜欢funclib.js,就到GitHub上去Star或Fork吧!(欢迎一起来玩)

GitHub Repository: https://github.com/CN-Tower/funclib.js

Downloads (鼠标右键点击,然后选“另存为...”)

funclib.core.js (@latest) Development Core, Uncompressed
funclib.js (@latest) Development Version, Uncompressed
funclib.min.js (@latest) Production Version, Minified
index.js (@latest) Server Side Version, Uncompressed
index.d.ts (@latest) TypeScript Definition File

Installation

# Install funclib.js
$ npm install funclib

# Use funclib
$ node
> var fn = require('funclib');
> var ps = [{name: 'Tom', age: 18}, {name: 'Bob', age: 22}];
> fn.log(ps, 'Persons');
// =>
==================================================================
                       [10:33:55] Persons 
------------------------------------------------------------------
[
  {
    "name": "Tom",
    "age": 18
  },
  {
    "name": "Bob",
    "age": 22
  }
]
==================================================================

> // var bob = fn.find(ps, function(p) { return p.name === 'Bob'; });
> // var bob = fn.find(ps, {name: 'Bob'});
> var p = fn(ps).find({name: 'Bob'}).set('name', 'Lee').val();
> fn.log(p, 'Person');
// =>
==================================================================
                       [10:33:55] Person
------------------------------------------------------------------
{
  "name": "Lee",
  "age": 22
}
==================================================================

Type

fn.typeOf
检查值的类型
fn.typeOf(value, type_, ...types);
@param value : any
接收一个任意类型的值
@param type_ : string
接收一个类型字符串,可以是类型简写(如:"udf" 对应 "undefined"),也可以是js标准类型的 全称(如:"string"),或者类型的枚举或数组(如:'str', 'arr' 或 ['str, arr'])
@param types: ...string[]|string[]
'arr' | 'obj' | 'fun' | 'str' | 'num' | 'bol' | 'udf' | 'nul' | 'ptn' | string | string[];

fn.typeOf('test', 'str');     // true
fn.typeOf('test', 'string');  // true
fn.typeOf(() => {}, 'fun');   // true
fn.typeOf([], 'arr');         // true
fn.typeOf({}, 'obj');         // true
fn.typeOf([], 'obj');         // false
fn.typeOf([], 'object');      // true
fn.typeOf(null, 'obj');       // false
fn.typeOf(null, 'object');    // true
fn.typeOf(undefined, 'str', 'udf');   // true
fn.typeOf(undefined, ['str', 'udf']); // true

fn.typeVal
先检查值的类型,如果是true则返回该值,否则返回false
fn.typeVal(value, type_);
@param value : any
接收一个任意类型的值
@param type_ : string
接收一个类型字符串,可以是类型简写(如:"udf" 对应 "undefined"),也可以是js标准类型的 全称(如:"string"),或者类型的枚举或数组(如:'str', 'arr' 或 ['str, arr'])
@param types: ...string[]|string[]
'arr' | 'obj' | 'fun' | 'str' | 'num' | 'bol' | 'udf' | 'nul' | 'ptn' | string | string[];

fn.typeVal('test', 'str');       // test
fn.typeVal(true, 'bol');         // true
fn.typeVal([], 'obj');           // false
fn.typeVal([], 'str', 'arr');    // []
fn.typeVal([], ['str', 'arr']);  // []

fn.isStr
判断类型是否为:string
fn.isStr(value);
@param value : any
接收一个任意类型的值

fn.isStr('true');  // true
fn.isStr(true);    // false

fn.isNum
判断类型是否为:number
fn.isStr(value, impure?);
@param value : any
接收一个任意类型的值
@param impure : boolean = false
是否包含NaN和Infinite

fn.isNum(NaN);        // false
fn.isNum(NaN, true);  // true
fn.isNum('123');      // false
fn.isNum(123);        // true

fn.isBol
判断类型是否为:boolean
fn.isBol(value);
@param value : any
接收一个任意类型的值

fn.isBol('true');  // false
fn.isBol(true);    // true

fn.isFun
判断类型是否为:function
fn.isFun(value);
@param value : any
接收一个任意类型的值

fn.isFun('true');  // false
fn.isFun([].map);  // true

fn.isNul
判断是否为:null
fn.isNul(value);
@param value : any
接收一个任意类型的值

fn.isNul('null');  // false
fn.isNul(null);    // true

fn.isUdf
判断类型是否为:undefined
fn.isUdf(value);
@param value : any
接收一个任意类型的值

fn.isUdf('');           // false
fn.isUdf(undefined);    // true

fn.isErr
判断类型是否为:Error
fn.isErr(value);
@param value : any
接收一个任意类型的值

fn.isErr(new Error('error'));  // true
fn.isErr(true);                // false

fn.isDat
判断类型是否为:Date
fn.isDat(value);
@param value : any
接收一个任意类型的值

fn.isDat(new Data());  // true
fn.isDat(123);         // false

fn.isReg
判断类型是否为:RegExp
fn.isReg(value);
@param value : any
接收一个任意类型的值

fn.isReg(new RegExp('test'));  // true
fn.isReg(/test/);              // true

fn.isArr
判断类型是否为:Array
fn.isArr(value);
@param value : any
接收一个任意类型的值

fn.isArr(new Array());  // true
fn.isArr([]);           // true
fn.isArr({});           // false

fn.isObj
判断是否为:正常Object
fn.isObj(value);
@param value : any
接收一个任意类型的值

fn.isObj(new Object());  // true
fn.isObj({});            // true
fn.isObj([]);            // false

Array

fn.array
返回一个指定长度和默认值的数组
fn.array(length, value?);
@param length : number
数组长度
@param value : any|function [?]
默认值,不传默认返回一个指定长度的range;如果是该参数为函数,函数以数组索引为参数,取函数的返回值为默认值

fn.array(5);               // [0, 1, 2, 3, 4]
fn.array(5, 0);            // [0, 0, 0, 0, 0]
fn.array(5, 'test');       // ['test', 'test', 'test', 'test', 'test']
fn.array(5, i => 2 * i);   // [0, 2, 4, 6, 8]

fn.range
返回一个范围数组
fn.range(start?, length);
@param start : number [?]
起始值
@param length : number
数组长度,若为负数则生成倒序的数组

fn.range(5);        // [0, 1, 2, 3, 4]
fn.range(-5);       // [0, -1, -2, -3, -4]
fn.range(2, 5);    // [2, 3, 4, 5, 6]
fn.range(2, -5);   // [2, 1, 0, -1, -2]

fn.toArr
值数组化
fn.toArr(value);
@param value : any
传入的值

fn.toArr();         // [undefined]
fn.toArr('test');   // ['test']
fn.toArr(['test']); // ['test']

fn.indexOf
寻找值在数组中的索引
fn.indexOf(srcArr, predicate);
@param srcArr : array
传入的数组
@param predicate : object|function|any
过滤条件,可以是一个任意类型的值,也可以是一个对象,或者是一个函数。
如果是对象,则判断是否为数组元素的子对象;如果是数组,则以数组元素为参数判断返回值的真假。

var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 18}];

fn.indexOf(persons, {name: 'LiLi'});             // -1
fn.indexOf(persons, {name: 'Tom'});              // 1
fn.indexOf(persons, ps => ps.name === 'Tom');    // 1
fn.indexOf(['Tom', 'Jerry', 'Marry'], 'Marry');  // 2

fn.find
根据条件寻找值
fn.find(srcArr, predicate);
@param srcArr : array
传入的值
@param predicate : object|function|any
寻找条件,可以是一个对象,或者是一个函数。
如果是对象,则判断是否为数组元素的子对象;如果是数组,则以数组元素为参数判断返回值的真假。

var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 18}];
fn.find(persons, {name: 'Tom'});            // {name:'Tom', age: 22}
fn.find(persons, ps => ps.name === 'Tom');  // {name:'Tom', age: 22}

fn.filter
根据条件取过滤值
fn.filter(srcArr, predicate);
@param srcArr : array
传入的数组
@param predicate : object|function|any
过滤条件,可以是一个对象,或者是一个函数。
如果是对象,则判断是否为数组元素的子对象;如果是数组,则以数组元素为参数判断返回值的真假。

var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 18}];
fn.filter(persons, {name: 'Tom'});             // [{name:'Tom', age: 22}]
fn.filter(persons, ps => ps.name === 'Tom');   // [{name:'Tom', age: 22}]

fn.reject
根据条件过滤值
fn.reject(srcArr, predicate);
@param srcArr : array
传入的数组
@param predicate : object|function|any
过滤条件,可以是一个对象,或者是一个函数。
如果是对象,则判断是否为数组元素的子对象;如果是数组,则以数组元素为参数判断返回值的真假。

var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 18}];
fn.reject(persons, {name: 'Tom'});             // [{name:'Jerry', age: 18}]
fn.reject(persons, ps => ps.name === 'Tom');   // [{name:'Jerry', age: 18}]

fn.contains
判断数组是否包含符合条件的值
fn.contains(srcArr, predicate);
@param srcArr : array
传入的数组
@param predicate : object|function|any
过滤条件,可以是一个任意类型的值,也可以是一个对象,或者是一个函数。
如果是对象,则判断是否为数组元素的子对象;如果是数组,则以数组元素为参数判断返回值的真假。

var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 18}];
fn.contains(persons, {name: 'LiLi'});              // false
fn.contains(persons, {name: 'Tom'});               // true
fn.contains(persons, ps => ps.name === 'Tom');     // true
fn.contains(['Tom', 'Jerry', 'Marry'], 'Marry');   // true

fn.drop
去掉Boolean()后为false和空数组或对象的值
fn.drop(srcArr:, isDrop0?);
@param srcArr : array
传入的数组
@param isDrop0 : boolean = false
是否去掉0,默认不去掉

var arr = [null, undefined, false, {}, [], 0, 'test'];
fn.drop(arr)          // [0, 'test']
fn.drop(arr, true)    // ['test']

fn.flatten
把有结构的数组打散,减少层数
fn.flatten(srcArr, isDeep?);
@param srcArr : array
传入的数组
@param isDeep : boolean = false
是否全部打散

var arr = [1, [2, 3, [4, [5]], 6], 7];
fn.flatten(arr)          // [1, 2, 3, [4, [5]], 6, 7]
fn.flatten(arr, true)    // [1, 2, 3, 4, 5, 6, 7]

fn.pluck
把结构中的字段取出合并到一个数组中
fn.pluck(srcArr, path);
@param srcArr : array
传入的数组
@param path : string
内部对象字段所在的路径

var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 18}];
fn.pluck(persons, '/name')    // ['Tom', 'Jerry']

fn.uniq
去重或根据字段去重
fn.uniq(srcArr, path?, isDeep?);
@param srcArr : array
传入的数组
@param path : string [?]
去重字段
@param isDeep : boolean = true
是否对比数组和对象

var arr1 = [0, {}, 0, false, null, false, [], [], {}, 'test', 'test']
var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 22}];

fn.uniq(arr1)              // [0, {}, false, null, [], 'test']
fn.uniq(arr1, false)       // [0, {}, false, null, [], [], {}, 'test']
fn.uniq(persons, '/name')  // [Tom, Jerry]
fn.uniq(persons, '/age')   // [Tom]

fn.forEach
遍历数组或类数组
fn.forEach(srcObj, iteratee);
@param srcObj : array|object
传入的数组或类数组
@param iteratee : function
项处理函数

var divs = document.querySelectorAll('div');
fn.forEach(divs, function(div) { // Do something... }); // name \n age

fn.sortBy
返回对象数组根据字段排序后的副本
fn.sortBy(srcArr, field, isDesc?);
@param srcArr : array
传入的需要排序的数组
@param field : string
需要排序的字段,或 字段路径
@param isDesc : boolean = false
是否降序,默认false

var persons = [
  {name:'Tom', age: 22, indexes: {height: 185, weight: 68}},
  {name:'Bob', age: 22, indexes: {height: 180, weight: 75}},
  {name:'Jerry', age: 18, indexes: {height: 175, weight: 70}}
];

fn.sortBy(persons, 'age');              // [Bob, Jerry, Tom]
fn.sortBy(persons, 'age', false);       // [Tom, Jerry, Bob]
fn.sortBy(persons, '/indexes/height');  // [Jerry, Bob, Tom]
fn.sortBy(persons, '/indexes/weight');  // [Tom, Bob, Jerry]

Object

fn.len
获取对象的元素、自有属性或参数的个数
fn.len(srcObj);
@param srcObj : any
传入的对象

fn.len(null);                // 0
fn.len('Tom');               // 3
fn.len({name: 'Tom'});       // 1
fn.len(['x']);               // 1
fn.len(x => console.log(s)); // 1

fn.has
判断对象是否存在某自有属性
fn.has(srcObj, property);
@param srcObj : object
传入的对象
@param property : string
判断是否存在的属性

var tom = {name: 'Tom', age: 28};
fn.has(tom, 'name');   // true
fn.has(tom, 'sex');    // false
fn.has(null, 'name');  // false

fn.get
返回对象或子孙对象的属性,可判断类型
fn.get(srcObj, path, type?);
@param srcObj : object
目标对象
@param path : string
属性的路径(可以以“.”分隔,也可以以“/”分隔。)
@param types : ...string[]|string[]
'arr' | 'obj' | 'fun' | 'str' | 'num' | 'bol' | 'udf' | 'nul' | string | string[];

var obj1 = {name: 'Obj', metadata: {subObj: {name: 'Tom'}}};
var obj2 = {name: 'Obj', metadata: null};
var Arr1 = [{name: 'Tom'}];
fn.get(obj1, '.metadata.subObj.name');         // Tom
fn.get(obj1, '/metadata/subObj/name');         // Tom
fn.get(obj1, '/metadata/subObj/name', 'str');  // Tom
fn.get(obj2, '/metadata/subObj/name', 'bol');  // false
fn.get({}, '/metadata/subObj/name');           // undefined
fn.get(obj2, '/metadata/subObj/name');         // undefined
fn.get(Arr1, '/0/name');                       // Tom

fn.set
设置对象或子孙对象的属性
fn.get(srcObj, path, value);
@param srcObj : object
目标对象
@param path : string
属性的路径(可以以“.”分隔,也可以以“/”分隔。)
@param value : any
任意类型的值

var obj1 = {name: 'Obj', metadata: {subObj: {name: 'Tom'}}};
var obj2 = {name: 'Obj', metadata: null};
var Arr1 = [{name: 'Tom'}];

fn.set(obj1, '.metadata.subObj.name', 'tom');  // obj1.metadata.subObj.name === 'tom'
fn.set(null, '/metadata/subObj/name');         // null
fn.set(obj2, '/metadata/subObj/name');         // {name: 'Obj', metadata: null}
fn.set(Arr1, '/0/name', 'Bob');                // [{name: 'Bob'}]

fn.keys
获取对象的键数组
fn.keys(srcObj);
@param srcObj : object
目标对象

fn.keys({name: 'Tom', age: 28});  // ['name': 'age']
fn.keys(['name', 'age']);         // ['0', '1']

fn.pick
获取对象的部分属性
fn.get(srcObj, predicate);
@param srcObj : object
目标对象
@param predicate : ...string[]|string|function
需要获取的属性或属性需满足的条件

fn.pick({name: 'Tom', age: 28}, 'name');                  // {name: 'Tom'}
fn.pick({name: 'Tom', age: 28}, 'name', 'age');           // {name: 'Tom', age: 28}
fn.pick({name: 'Tom', age: 28}, ['name', 'age', 'sex']);  // {name: 'Tom', age: 28}
fn.pick({name: 'Tom', age: 28}, {default: undefined}, ['name', 'age', 'sex']);  // {name: 'Tom', age: 28, sex: undefined}
fn.pick({name: 'Tom', age: 28}, (k, v) => v === 28);      // {age: 28}

fn.extend
给目标对象赋值
fn.extend(tarObj, srcObj, propList?);
@param tarObj : object
目标对象
@param srcObj : object
源对象
@param predicate : ...string[]|string|function [?]
需要赋值的属性,不传默认为src的全部属性

var tom = {name: 'Tom'};
var jerry = {name: 'Jerry', age: 28, sex: 'm'};
fn.extend(tom, jerry, ['age', 'sex']);
console.log(tom);   // {name: 'Tom', age: 28, sex: 'm'}

fn.forIn
遍历对象的可数自有属性
fn.forIn(srcObj, iteratee);
@param srcObj : object
传入的对象
@param iteratee : function
项处理函数

var tom = {name: 'Tom', age: 28};
fn.forIn(tom, prop => console.log(prop)); // name \n age

fn.deepCopy
深拷贝对象或数组
fn.deepCopy(srcObj);
@param srcObj : object
目标对象

var tom = {name: 'Tom', age: 22};
var _tom = fn.deepCopy(tom);
tom.age = 28;
console.log(_tom.name);   // 22

fn.isEmpty
判断对象是否为空
fn.isEmpty(srcObj);
@param srcObj : object
目标对象

fn.isEmpty({});            // true
fn.isEmpty([]);            // true
fn.isEmpty({name: 'Tom'}); // false
fn.isEmpty(null);          // false

fn.isDeepEqual
判断数组或对象是否相等
fn.isDeepEqual(obj1, obj2, isStrict?);
@param obj1 : object|array
对象1
@param obj2 : object|array
对象2
@param isStrict : boolean = false
是否严格相等,默认false

fn.isDeepEqual([], {})                                                    // false
fn.isDeepEqual([{name: 'Tom', age: 21}], [{name: 'Tom', age: 22}])        // false
fn.isDeepEqual([{name: 'Tom', age: 21}], [{age: 21, name: 'Tom'}])        // true
fn.isDeepEqual([{name: 'Tom', age: 21}], [{age: 21, name: 'Tom'}], true)  // false

Math

fn.random
返回一个指定范围的随机数
fn.random(start, end?);
@param start : number
最大限定,或最小起始值
@param end : number [?]
最大限定,不传则sta为最大限定

fn.random(5);     // 2
fn.random(5);     // 3
fn.random(5, 10); // 6
fn.random(5, 10); // 9

fn.gid
返回一个指定长度(默认12位)的随机ID
fn.gid(len?);
@param length : number = 12
ID的长度,默认12位

fn.gid();     // '27OBAOJDLKK0'
fn.gid(8);    // '1J3XL19O'

fn.gcolor
返回一个随机色值
fn.gcolor();

fn.gcolor(); // #2913ba
fn.gcolor(); // #d0b1ab

Time

fn.interval
循环定时器
fn.interval(timerId, duration?, callback?);
@param timerId : string [?]
定时器名称
当fn.interval()正常传值时,返回定时器ID
当fn.interval()传入定时器名称时,返回带stop和clear方法和id属性的对象
@param duration : number|false|null [?]
间隔时间,默认为0
当传入false或null时,则停止定时器
@param callback : function
定时触发的函数

// 设置名称为my-timer的循环定时器
fn.interval('my-timer', 1000, () => console.log(111));
// 清除名称为my-timer的循环定时器
// fn.interval('my-timer', false);
// fn.interval('my-timer').stop();
fn.interval('my-timer').clear();

// 设置延循环时器
var timerId = fn.interval(1000, () => console.log(111));
// 清除延循环时器
clearInterval(timerId);

fn.timeout
延时定时器
fn.timeout(timerId, duration?, callback?);
@param timerId : string [?]
定时器名称
当fn.timeout()正常传值时,返回定时器ID
当fn.timeout()传入定时器名称时,返回带stop和clear方法和id属性的对象
@param duration : number|false|null [?]
间隔时间,默认为0
当传入false或null时,则停止定时器
@param callback : function
定时触发的函数

// 设置名称为my-timer的延时定时器
fn.timeout('my-timer', 1000, () => console.log(222));
// 清除名称为my-timer的延时定时器
// fn.timeout('my-timer', false);
// fn.timeout('my-timer').stop();
fn.timeout('my-timer').clear();

// 设置延时定时器
var timerId = fn.timeout(1000, () => console.log(111));
// 清除延时定时器
clearTimeout(timerId);

fn.defer
延迟执行函数
fn.defer(func);
@param func : function
延迟执行的函数

// 相当于:
setTimeout(func, 0);

fn.timestamp
返回一个时间戳
fn.timestamp(time);
@param time : date|string|number
传入一个日期对象、时间字符串或时间辍

fn.timestamp(new Date('2018-06-06 12:30')); // 1528259400000

fn.time
返回一个时间戳, 同:fn.timestamp
fn.time(time);
@param time : date|string|number
传入一个日期对象、时间字符串或时间辍

fn.time(new Date('2018-06-06 12:30')); // 1528259400000

fn.asUtcTime
返回一个时间戳
fn.asUtcTime(time);
@param time : date|string|number
传入一个日期对象、时间字符串或时间辍

fn.asUtcTime(new Date('2018-06-06 12:30')); // 1528288200000

fn.fmtDate
获取格式化的时间字符串
fn.fmtDate(fmtStr, time);
@param fmtStr : string
时间格式字符串,如:yy-MM-dd hh:mm:ss, MM-dd hh:mm 等
@param time : date|string|number
传入一个日期对象、时间字符串或时间辍

var date = new Date('2018-06-06 12:30');

fn.fmtDate('yyyy-MM-dd hh:mm', 1528259400000);  // 2018-06-06 12:30
fn.fmtDate('yy-MM-dd hh:mm', date);             // 18-06-06 12:30

fn.fmtUTCDate
获取格式化的UTC时间字符串
fn.fmtUTCDate(fmtStr, time);
@param fmtStr : string
时间格式字符串,如:yy-MM-dd hh:mm:ss, MM-dd hh:mm 等
@param time : date|string|number
传入一个日期对象、时间字符串或时间辍

var date = new Date('2018-06-06 12:30');

fn.fmtUTCDate('yyyy-MM-dd hh:mm', 1528259400000);
fn.fmtUTCDate('yy-MM-dd hh:mm', date);

fn.fmtXYZDate
获取格式化指定时差的时间字符串
fn.fmtXYZDate(fmtStr, time, offset);
@param fmtStr : string
时间格式字符串,如:yy-MM-dd hh:mm:ss, MM-dd hh:mm 等
@param time : date|string|number
传入一个日期对象、时间字符串或时间辍
@param offset : number
与UTC的时差

var date = new Date('2018-06-06 12:30');

fn.fmtXYZDate('yyyy-MM-dd hh:mm', 1528259400000, 5.5 * 60 * 60 * 1000);
fn.fmtXYZDate('yy-MM-dd hh:mm', date, 5.5 * 60 * 60 * 1000);

String

fn.match
类型匹配,默认情况还可以写表达式
fn.match(srcStr, cases, isExec?);
@param srcStr : string
用来匹配的字符串
@param cases :object
匹配对象,可以包含'default'项为默认匹配项
匹配项,可以包含'@next'值,当包含该值时,匹配结果同其下一项相同
@param isExec : boolean = true
匹配对象的值为函数时,是否调用该函数,默认true

fn.match('b', {'a': 'aaa', 'b': 'bbb', c: 'ccc'});         // 'bbb'
fn.match('b', {'a': 'aaa', 'b': '@next', c: 'ccc'});       // 'ccc'
fn.match('c', {'a': 'aaa', 'b': () => 'bbb', c: 'ccc'});  // undefine
fn.match('c', {'a': 'aaa', b: 'bbb', 'default': 'ddd'});  // 'ddd'
fn.match('c', {                                            // 'ccc'
  'a': 'aaa',
  'default': s => s === 'c' ? 'ccc' : 'ddd'
});

fn.pretty
转换成格式化字符串
fn.pretty(srcObj);
@param srcObj : any
需要格式化的值

fn.pretty([{name: 'tom', age: 22}]);  // =>
[
  {
    "name": "tom",
    "age": 22
  }
]

fn.escape
编码HTML字符串
fn.escape(srcStr);
@param srcStr : string
传入的字符串

fn.escape('<div></div>');  // &lt;div&gt;&lt;/div&gt;

fn.unescape
解码HTML字符串
fn.unescape(srcStr);
@param srcStr : string
传入已编码的字符串

fn.unescape('&lt;div&gt;&lt;/div&gt;');  // <div></div>

fn.capitalize
使字符串首字母大写
fn.capitalize(srcStr);
@param srcStr : string
需要首字母大写的字符串

fn.capitalize('aaa');  // Aaa
fn.capitalize(true);   // true

fn.fmtCurrency
格式化显示货币
fn.fmtCurrency(number, digit?);
@param number : number
传入货币数值
@param digit : number = 2
保留小数位数

'¥' + fn.fmtCurrency(199999999);    // ¥199,999,999.00
'¥' + fn.fmtCurrency(199999999, 4); // ¥199,999,999.0000

fn.maskString
编码字符串或其子串
fn.maskString(srcStr, mask?, start, length);
@param srcStr : any
传入字符串
@param mask : string
掩码字符
@param start : number
开始位置
@param length : number
编码长度

fn.maskString(18770347428, 3, 4);         // 187****7428
fn.maskString(18770347428, 3);            // 187********
fn.maskString('18770347428', 'x', 3, 4);  // 187xxxx7428
fn.maskString('测试双字节', 2, 1);         // 测试**字节

fn.cutString
裁切字符串到指定长度
fn.cutString(srcStr, length);
@param srcStr : string
传入字符串
@param length : number
保留长度

fn.cutString('test测试aaaaaaa!', 6); // test测...
fn.cutString('test测试aaaaaaa!', 4); // test...

fn.parseQueryStr

fn.stringfyQueryStr
解析Url参数成对象
fn.parseQueryStr(url);
@param url : string
需要解析的URL字符串

var url = 'https://www.baidu.com/s?wd=%E7%99%BE%E5%BA%A6&rsv_spt=10';
fn.log(fn.parseQueryStr(url));  // {"wd": "百度", "rsv_spt": "10"}

fn.stringfyQueryStr
把对象编译成Url参数
fn.stringfyQueryStr(obj);
@param obj : object
需要编译的对象

var params = {name: 'Tom', age: 28};
fn.log(fn.stringfyQueryStr(params)); // ?name=Tom&age=28

RegExp

fn.setPattern
设置一个正则表达式
fn.setPattern(ptnMap, pattern);
@param ptnMap : string|object
正则名称,或正则Object(key为名称,val为正则表达式)
@param pattern : regexp [?]
ptnMap为正则名称,传入正则表达式

fn.setPattern('myPtn', /test/);
fn.setPattern({myPtn: /test/});

fn.matchPattern('abc', 'myPtn');    // false
fn.matchPattern('test', 'myPtn');   // true

fn.getPattern
获取一个通用的正则表达式
fn.getPattern(type_, limit?);
@param type_ : string
传入正则名称
正则名称主要有:
cnChar: 汉字
dbChar: 双字节字符
mobPhone: 中国大陆电话号码
telPhone 中国大陆手机号码
email: Email
idCard: 中国大陆身份证
uuid: uuid: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
base64Code: Base64编码格式
mac: Mac地址
domain: 域名
port: 端口号
ip: IP地址
domainUrl: 域Url
url: Url
domainWithPortUrl: 带端口的 域Url
withPortUrl: 带端口的 Url
@param limit : boolean = true
是否强制加首尾限制(^和$),默认为true

fn.getPattern('cnChar');       // /^[\u4e00-\u9fa5]+$/
fn.getPattern('cnChar', false); // /[\u4e00-\u9fa5]+/

fn.fntestpattern
用一个或几个通用正则测试
fn.matchPattern(srcStr, type_, limit?);
@param srcStr : string
传入需要测试的字符串
@param type_ : ...string[]|string[]
正则名称,可以是一个名称或多个名称
@param limit : boolean = true
是否强制加首尾限制(^和$),默认为true

fn.fntestpattern('cntower@yahoo.com', 'mobPhone'); // false
fn.fntestpattern('cntower@yahoo.com', 'email');    // true

fn.matchPattern
与一个或几个通用正则匹配
fn.matchPattern(srcStr, type_, limit?);
@param srcStr : string
传入需要匹配的字符串
@param type_ : ...string[]|string[]
正则名称,可以是一个名称或多个名称
@param limit : boolean = true
是否强制加首尾限制(^和$),默认为true

fn.matchPattern('cntower@yahoo.com', 'mobPhone'); // false
fn.matchPattern('cntower@yahoo.com', 'email');    // [...mtchResult]

Function

fn.restArgs
获取函数的剩余参数
fn.restArgs(srcFunc);
@param srcFunc : function
需要获取剩余参数的原函数

fn.restArgs(function(args) {fn.log(args)})('a', 'b'); // ['a', 'b']

fn.throttle
节流函数,适用于限制resize和scroll等函数的调用频率
fn.throttle(func, wait, options?);
@param func : function
需要节流的函数
@param wait : number
节流时间
@param options : object [?]
leading: boolean = true
trailing: boolean = true

var i = 0, duration = 500;
var log = fn.throttle(() => fn.log(i, 'throttle'), 2000);
doLog();
function doLog() {
  fn.timeout(duration, () => {
    i ++;
    log();
    if (i === 8) duration = 2500;
    doLog();
  });
}

fn.debounce
防抖函数, 适用于获取用户输入
fn.debounce(func, wait, immediate?);
@param func : function
需要防抖的函数
@param wait : number
节流时间
@param options : object [?]
leading: boolean = false
maxing: boolean = false
maxWait: number = Math.max(0, wait)
trailing: boolean = true

var i = 0, duration = 500;
var log = fn.debounce(() => fn.log(i, 'debounce'), 2000, true);
doLog();
function doLog() {
  fn.timeout(duration, () => {
  i ++;
  log();
  if (i === 8) duration = 2500;
    doLog();
  });
}

Dom

fn.fullScreen
全屏显示HTML元素
fn.fullScreen(el);
@param el : HTMLElement
html元素

//全屏显示页面
fn.fullScreen(document.querySelector('html'));

fn.exitFullScreen
退出全屏显示
fn.exitFullScreen();

//退出全屏显示
fn.exitFullScreen();

fn.isFullScreen
检测是否全屏状态
fn.isFullScreen();

fn.isFullScreen();  // false

fn.fullScreenChange
全屏显示变化事件
fn.fullScreenChange(callback?);
@param callback function|false [?]
callback为函数,则callback为回调并开始全屏事件监听,为fasle则关闭全屏事件监听

function fullsScreenHandler() { //Do Something... }
fn.fullScreenChange(() => fullsScreenHandler);

Loger

fn.chalk
返回带颜色的字符串
fn.chalk(srcStr, color?);
@param srcStr : string
原字符串
@param color : 'grey'|'blue'|'cyan'|'green'|'magenta'|'red'|'yellow'

console.log(fn.chalk('test', 'cyan'));

fn.print
在控制台打印值
fn.chalk(value, color?);
@param value : any
任意需要打印的值
@param color : 'grey'|'blue'|'cyan'|'green'|'magenta'|'red'|'yellow'

fn.print('test', 'cyan');

fn.log
强大的打印函数(服务端还可带颜色)
fn.log(value, title?, configs?);
@param value : any
需要打印的值
@param title : string|boolean [?]
为string值时,文章标题
为boolean值时,表示是否带格式线
@param configs : object [?]
title: string,
width: number = 66 [20-100],
isFmt: boolean [?]
isShowTime: boolean = true
pre: boolean = false,
end: boolean = false
ttColor: 'grey'|'blue'|'cyan'|'green'|'magenta'|'red'|'yellow'
color: 'grey'|'blue'|'cyan'|'green'|'magenta'|'red'|'yellow' = 'cyan'

fn.log([{name: 'tom', age: 22}], false);
// =>
[15:27:16] ( funclib(v3.5.5) ):
[
  {
    "name": "tom",
    "age": 22
  }
]

fn.log([{name: 'tom', age: 22}], 'Tom Info');
// =>
==================================================================
                      [15:26:42] Tom Info
------------------------------------------------------------------
[
  {
    "name": "tom",
    "age": 22
  }
]
==================================================================

fn.log([{name: 'tom', age: 22}]);
fn.log('Test Title', {title: 'Tom Infooooooooooooooooooooooooooooooooooooooooooo'});
fn.log('Test Config', {title: 'Tom Info', width: 80, color: 'red', ttColor: 'blue'});
fn.log(() => {console.log(111)}, 'Function');

Tools

fn.rd
读文件
fn.rd(file);
@param file : string
文件路径

fn.rd('C:\\Users\\Administrator\\Desktop\\test\\test.txt');

fn.wt
写文件
fn.wt(file, text, flag?);
@param file : string
文件路径
@param text : string
文件内容
@param flag : 'w'|'a' = 'w'
w:重写,a:追加

fn.wt('C:\\Users\\Administrator\\Desktop\\test\\test.txt', 'Test file');

fn.cp
复制文件或文件夹
fn.cp(src, dist);
@param src : string
原文件或文件夹路径
@param dist : string
目标文件或文件夹路径

fn.cp('C:\\Users\\Administrator\\Desktop\\test\\test.txt', 'C:');

fn.mv
移动文件或文件夹
fn.mv(src, dist);
@param src : string
原文件或文件夹路径
@param dist : string
目标文件或文件夹路径

fn.mv('C:\\Users\\Administrator\\Desktop\\test\\test.txt', 'C:test.txt');

fn.rm
删除文件或文件夹
fn.rm(src);
@param src : string
目标文件或文件夹路径

fn.rm('C:\\Users\\Administrator\\Desktop\\test\\test.txt');

fn.mk
创建文件夹(注:创建文件使用fn.wt)
fn.mk(dist);
@param src : string
文件夹路径

fn.mk('C:\\Users\\Administrator\\Desktop\\test');

fn.size
获取文件的大小
fn.size(file, unit?, digit?);
@param file : string
文件路径
@param unit : 'b'|'kb'|'mb'|'gb'|'tb' = 'kb'
文件大小的单位
@param digit : number = 2
保留小数位数

fn.size('C:\\Users\\Administrator\\Desktop\\test\\test.txt');

fn.clear
命令行清屏
fn.clear();

fn.clear();

fn.copyText
复制文本到粘贴板
fn.copyText(text);
@param text : string
需要复制到粘贴板的文本

可使用:Ctrl + V,粘贴复制的内容

Progress

fn.progress.start
开启进度,并传入参数
fn.start(title, options?);
@param title: string
@param options: object [?]
width: number = 40
type : 'bar'|'spi' = 'bar'

fn.progress.start({title: 'Test', type: 'spi'});
/ Test
fn.progress.start({title: 'Test'});
Test [================                        ] 40%

fn.progress.stop
结束进度,结束后触发回调
fn.stop(onStopped?);
@param onStopped : function [?]
结束时的回调

fn.progress.stop(() => { // Do something... });

fn.chain
可把第一个参数传入fn.chain(),并返回一个链式调用对象(同: fn())
fn.chain(data).method(...args)
@param data : any
method方法的第一个参数
@param args : ...any[]
method方法除去第一个参数后的剩余参数

var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 18}];
fn.chain(persons).find({name: 'Tom'}).val();                               // {name:'Tom', age: 22}
fn.chain(persons).find(ps => ps.name === 'Tom').set('name', 'Bob').val();  // {name:'Bob', age: 22}

fn().method
可把第一个参数传入fn(),剩余的参数传入method中,并返回一个链式调用对象
fn(data).method(...args);
@param data : any
method方法的第一个参数
@param args : ...any[]
method方法除去第一个参数后的剩余参数

var persons = [{name:'Tom', age: 22}, {name:'Jerry', age: 18}];
fn(persons).find({name: 'Tom'}).val();                               // {name:'Tom', age: 22}
fn(persons).find(ps => ps.name === 'Tom').set('name', 'Bob').val();  // {name:'Bob', age: 22}

Tricks

fn.noConflict
释放fn变量占用权
fn.noConflict();

fn.noConflict();  // [Funclib]
console.log(fn)   // undefined

fn.version
返回当前函数库版本
fn.version;

fn.version;  //3.5.5 

Change Log

2.2.6 2018-07

2.2.7 2018-08-31
【增加的方法】:
fn.match
fn.pretty
fn.pick
fn.escape
用法同fn.encodeHtml
fn.unescape
用法同fn.decodeHtml
【修改的方法】:
fn.parseQueryStr
修改于: fn.parseQueryString
fn.stringifyQueryStr
修改于: fn.stringifyQueryString
fn.isDeepEqual
增加isStrict参数

2.2.9 2018-08-31
【增加的方法】:
fn.isEmpty
【修改的方法】:
fn.extend
修改于: fn.overlay

2.2.10 2018-11-09
【增加的方法】:
fn.toArr
用法同fn.toArray
【修改的方法】:
fn.match
功能升级
- 增加“@dft”匹配项
- 增加“@pass”值匹配项
fn.sortBy
修复值为null、undefined、''等空值无法排序的问题
fn.interval
用法改造
- 调换参数位置
- 增加停止定时器的方法
fn.timeout
用法改造
- 调换参数位置
- 增加停止定时器的方法
fn.log
主要是参数位置的更换

3.1.5 2018-12-20
【删除的方法】:
fn.toArray()
用法同fn.toArr()
fn.encodeHtml()
用法同fn.escape()
fn.decodeHtml()
用法同fn.unescape()
【增加的方法】:
fn.range()
返回一个范围数组
fn.keys()
用法同Object.keys()
fn.size()
获取文件的大小
fn.noConflict()
释放fn变量名的占用权
【修改的方法】:
fn.interval()
用法改造
- 调换参数位置
fn.timeout()
用法改造
- 调换参数位置
fn.log()
增加时间可选配置

3.1.9 2018-12-22
【删除方法】:
fn.progress.start()
改为: fn.progress() 进度显示工具
【增加方法】:
fn.each()
同: fn.forEach() 遍历数组或类数组
【修改方法】:
fn.progress()
修改自: fn.progress.start()
【其它升级】:
[1]优化index.d.ts,有更好的vs-code体验

3.1.12 2018-1-03
【增加方法】:
fn.setPattern()
增加自定义的正则
【修改方法】:
fn.getPattern() && fn.matchPattern()
isNoLimit 修改为 limit
fn.typeOf()
增加type: 'ptn'
fn.match()
默认项:'@dft' 修改为:'$dft','@default' 修改为:'$default'
'@pass' 修改为:'@next'

3.3.1 2018-1-03
【删除方法】:
fn.setCookie() fn.getCookie() fn.rmCookie()
【增加方法】:
fn.asUtcTime()
把时间转为相同时间的格林尼治时间戳

3.3.1 2018-2-24
【增加方法】:
fn.time()
同:fn.timestamp()
fn.fmtUTCDate()
获取格式化的UTC时间字符串
fn.fmtXYZDate()
获取格式化指定时差的时间字符串
fn.print()
在控制台打印值
fn.clear()
命令行清屏
【其它修改】:

修复一些bug,如:fn.match()的@next