1. all:布尔全等判断
const all = (arr, fn = Boolean) => arr.every(fn);

all([4, 2, 3], x => x > 1); // true
all([1, 2, 3]); // true
  1. allEqual:检查数组各项相等
const allEqual = arr => arr.every(val => val === arr[0]);

allEqual([1, 2, 3, 4, 5, 6]); // false
allEqual([1, 1, 1, 1]); // true
  1. approximatelyEqual:约等于
const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon;

approximatelyEqual(Math.PI / 2.0, 1.5708); // true
  1. arrayToCSV:数组转CSV格式(带空格的字符串)
const arrayToCSV = (arr, delimiter = ',') =>
arr.map(v => v.map(x => `"${x}"`).join(delimiter)).join('\n'); arrayToCSV([['a', 'b'], ['c', 'd']]); // '"a","b"\n"c","d"'
arrayToCSV([['a', 'b'], ['c', 'd']], ';'); // '"a";"b"\n"c";"d"'
  1. arrayToHtmlList:数组转li列表
const arrayToHtmlList = (arr, listID) =>
(el => (
(el = document.querySelector('#' + listID)),
(el.innerHTML += arr.map(item => `<li>${item}</li>`).join(''))
))(); arrayToHtmlList(['item 1', 'item 2'], 'myListID');
  1. average:平均数
const average = (...nums) => nums.reduce((acc, val) => acc + val, 0) / nums.length;
average(...[1, 2, 3]); // 2
average(1, 2, 3); // 2
  1. averageBy:数组对象属性平均数

此代码段将获取数组对象属性的平均值

const averageBy = (arr, fn) =>
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0) /
arr.length; averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5
  1. bifurcate:拆分断言后的数组

可以根据每个元素返回的值,使用reduce()和push() 将元素添加到第二次参数fn中 。

const bifurcate = (arr, filter) =>
arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [[], []]);
bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]);
// [ ['beep', 'boop', 'bar'], ['foo'] ]
  1. castArray:其它类型转数组
const castArray = val => (Array.isArray(val) ? val : [val]);

castArray('foo'); // ['foo']
castArray([1]); // [1]
castArray(1); // [1]
  1. compact:去除数组中的无效/无用值
const compact = arr => arr.filter(Boolean);

compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]);
// [ 1, 2, 3, 'a', 's', 34 ]
  1. countOccurrences:检测数值出现次数
const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
  1. deepFlatten:递归扁平化数组
const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));

deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]
  1. difference:寻找差异(并返回第一个数组独有的)

此代码段查找两个数组之间的差异,并返回第一个数组独有的。

const difference = (a, b) => {
const s = new Set(b);
return a.filter(x => !s.has(x));
}; difference([1, 2, 3], [1, 2, 4]); // [3]
  1. differenceBy:先执行再寻找差异

在将给定函数应用于两个列表的每个元素之后,此方法返回两个数组之间的差异。

const differenceBy = (a, b, fn) => {
const s = new Set(b.map(fn));
return a.filter(x => !s.has(fn(x)));
}; differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [1.2]
differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], v => v.x); // [ { x: 2 } ]
  1. dropWhile:删除不符合条件的值

此代码段从数组顶部开始删除元素,直到传递的函数返回为true。

const dropWhile = (arr, func) => {
while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
return arr;
}; dropWhile([1, 2, 3, 4], n => n >= 3); // [3,4]
  1. flatten:指定深度扁平化数组

此代码段第二参数可指定深度。

const flatten = (arr, depth = 1) =>
arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), []); flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
  1. indexOfAll:返回数组中某值的所有索引

此代码段可用于获取数组中某个值的所有索引,如果此值中未包含该值,则返回一个空数组。

const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);

indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []
  1. intersection:两数组的交集
const intersection = (a, b) => {
const s = new Set(b);
return a.filter(x => s.has(x));
}; intersection([1, 2, 3], [4, 3, 2]); // [2, 3]
  1. intersectionWith:两数组都符合条件的交集

此片段可用于在对两个数组的每个元素执行了函数之后,返回两个数组中存在的元素列表。

const intersectionBy = (a, b, fn) => {
const s = new Set(b.map(fn));
return a.filter(x => s.has(fn(x)));
}; intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [2.1]
  1. intersectionWith:先比较后返回交集
const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);

intersectionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b)); // [1.5, 3, 0]
  1. minN:返回指定长度的升序数组
const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);

minN([1, 2, 3]); // [1]
minN([1, 2, 3], 2); // [1,2]
  1. negate:根据条件反向筛选
const negate = func => (...args) => !func(...args);

[1, 2, 3, 4, 5, 6].filter(negate(n => n % 2 === 0)); // [ 1, 3, 5 ]
  1. randomIntArrayInRange:生成两数之间指定长度的随机数组
const randomIntArrayInRange = (min, max, n = 1) =>
Array.from({ length: n }, () => Math.floor(Math.random() * (max - min + 1)) + min); randomIntArrayInRange(12, 35, 10); // [ 34, 14, 27, 17, 30, 27, 20, 26, 21, 14 ]
  1. sample:在指定数组中获取随机数
const sample = arr => arr[Math.floor(Math.random() * arr.length)];

sample([3, 7, 9, 11]); // 9
  1. sampleSize:在指定数组中获取指定长度的随机数

此代码段可用于从数组中获取指定长度的随机数,直至穷尽数组。 使用Fisher-Yates算法对数组中的元素进行随机选择。

const sampleSize = ([...arr], n = 1) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr.slice(0, n);
}; sampleSize([1, 2, 3], 2); // [3,1]
sampleSize([1, 2, 3], 4); // [2,3,1]
  1. shuffle:“洗牌” 数组

此代码段使用Fisher-Yates算法随机排序数组的元素。

const shuffle = ([...arr]) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr;
}; const foo = [1, 2, 3];
shuffle(foo); // [2, 3, 1], foo = [1, 2, 3]
  1. nest:根据parent_id生成树结构(阿里一面真题)

根据每项的parent_id,生成具体树形结构的对象。

const nest = (items, id = null, link = 'parent_id') =>
items
.filter(item => item[link] === id)
.map(item => ({ ...item, children: nest(items, item.id) }));

用法:

  const comments = [
{ id: 1, parent_id: null },
{ id: 2, parent_id: 1 },
{ id: 3, parent_id: 1 },
{ id: 4, parent_id: 2 },
{ id: 5, parent_id: 4 }
];
const nestedComments = nest(comments); // [{ id: 1, parent_id: null, children: [...] }]

函数

  1. attempt:捕获函数运行异常

该代码段执行一个函数,返回结果或捕获的错误对象。

onst attempt = (fn, ...args) => {
try {
return fn(...args);
} catch (e) {
return e instanceof Error ? e : new Error(e);
}
};
var elements = attempt(function(selector) {
return document.querySelectorAll(selector);
}, '>_>');
if (elements instanceof Error) elements = []; // elements = []
  1. defer:推迟执行
const defer = (fn, ...args) => setTimeout(fn, 1, ...args);

defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a'
  1. runPromisesInSeries:运行多个Promises
const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
const delay = d => new Promise(r => setTimeout(r, d)); runPromisesInSeries([() => delay(1000), () => delay(2000)]);
//依次执行每个Promises ,总共需要3秒钟才能完成
  1. timeTaken:计算函数执行时间
const timeTaken = callback => {
console.time('timeTaken');
const r = callback();
console.timeEnd('timeTaken');
return r;
}; timeTaken(() => Math.pow(2, 10)); // 1024, (logged): timeTaken: 0.02099609375ms
  1. createEventHub:简单的发布/订阅模式

创建一个发布/订阅(发布-订阅)事件集线,有emit,on和off方法。

  • 使用Object.create(null)创建一个空的hub对象。
  • emit,根据event参数解析处理程序数组,然后.forEach()通过传入数据作为参数来运行每个处理程序。
  • on,为事件创建一个数组(若不存在则为空数组),然后.push()将处理程序添加到该数组。
  • off,用.findIndex()在事件数组中查找处理程序的索引,并使用.splice()删除。
const createEventHub = () => ({
hub: Object.create(null),
emit(event, data) {
(this.hub[event] || []).forEach(handler => handler(data));
},
on(event, handler) {
if (!this.hub[event]) this.hub[event] = [];
this.hub[event].push(handler);
},
off(event, handler) {
const i = (this.hub[event] || []).findIndex(h => h === handler);
if (i > -1) this.hub[event].splice(i, 1);
if (this.hub[event].length === 0) delete this.hub[event];
}
});

用法:

const handler = data => console.log(data);
const hub = createEventHub();
let increment = 0; // 订阅,监听不同事件
hub.on('message', handler);
hub.on('message', () => console.log('Message event fired'));
hub.on('increment', () => increment++); // 发布:发出事件以调用所有订阅给它们的处理程序,并将数据作为参数传递给它们
hub.emit('message', 'hello world'); // 打印 'hello world' 和 'Message event fired'
hub.emit('message', { hello: 'world' }); // 打印 对象 和 'Message event fired'
hub.emit('increment'); // increment = 1 // 停止订阅
hub.off('message', handler);
  1. memoize:缓存函数

通过实例化一个Map对象来创建一个空的缓存。

通过检查输入值的函数输出是否已缓存,返回存储一个参数的函数,该参数将被提供给已记忆的函数;如果没有,则存储并返回它。

const memoize = fn => {
const cache = new Map();
const cached = function(val) {
return cache.has(val) ? cache.get(val) : cache.set(val, fn.call(this, val)) && cache.get(val);
};
cached.cache = cache;
return cached;
};

Ps: 这个版本可能不是很清晰,还有Vue源码版的:

/**
* Create a cached version of a pure function.
*/
export function cached<F: Function> (fn: F): F {
const cache = Object.create(null)
return (function cachedFn (str: string) {
const hit = cache[str]
return hit || (cache[str] = fn(str))
}: any)
}
  1. once:只调用一次的函数
const once = fn => {
let called = false
return function () {
if (!called) {
called = true
fn.apply(this, arguments)
}
}
};
  1. flattenObject:以键的路径扁平化对象

使用递归。

  • 利用Object.keys(obj)联合Array.prototype.reduce(),以每片叶子节点转换为扁平的路径节点。
  • 如果键的值是一个对象,则函数使用调用适当的自身prefix以创建路径Object.assign()。
  • 否则,它将适当的前缀键值对添加到累加器对象。
  • prefix除非您希望每个键都有一个前缀,否则应始终省略第二个参数。
const flattenObject = (obj, prefix = '') =>
Object.keys(obj).reduce((acc, k) => {
const pre = prefix.length ? prefix + '.' : '';
if (typeof obj[k] === 'object') Object.assign(acc, flattenObject(obj[k], pre + k));
else acc[pre + k] = obj[k];
return acc;
}, {}); flattenObject({ a: { b: { c: 1 } }, d: 1 }); // { 'a.b.c': 1, d: 1 }
  1. unflattenObject:以键的路径展开对象

与上面的相反,展开对象。

const unflattenObject = obj =>
Object.keys(obj).reduce((acc, k) => {
if (k.indexOf('.') !== -1) {
const keys = k.split('.');
Object.assign(
acc,
JSON.parse(
'{' +
keys.map((v, i) => (i !== keys.length - 1 ? `"${v}":{` : `"${v}":`)).join('') +
obj[k] +
'}'.repeat(keys.length)
)
);
} else acc[k] = obj[k];
return acc;
}, {}); unflattenObject({ 'a.b.c': 1, d: 1 }); // { a: { b: { c: 1 } }, d: 1 }

这个的用途,在做Tree组件或复杂表单时取值非常舒服。

字符串

  1. byteSize:返回字符串的字节长度
const byteSize = str => new Blob([str]).size;

byteSize('												

JavaScript 函数工具的更多相关文章

  1. 利用JavaScript函数对字符串进行加密

    加密.解密问题对我来说一直是很神秘的,感到神奇无比. 理论了解 前段时间看到关于利用JavaScript函数unescape()和escape()对字符串进行替换处理.通过查资料得知, escape( ...

  2. 实例演示 kino.razor (前端 Javascript 模板工具,Razor 风格)的使用

    前言 对于习惯了 ASP.NET MVC Razor 模板引擎的人来说,比如我,一直在寻找前端 Javascript 端的 Razor 模板工具.这之前,我也了解到很多Javascript 端的模板工 ...

  3. 第八章:Javascript函数

    函数是这样一段代码,它只定义一次,但可能被执行或调用任意次.你可能从诸如子例程(subroutine)或者过程(procedure)这些名字里对函数概念有所了解. javascript函数是参数化的: ...

  4. JavaScript 开发工具webstrom使用指南

    本文给大家推荐了一款非常热门的javascript开发工具webstrom,着重介绍了webstrom的特色功能.设置技巧.使用心得以及快捷键汇总,非常的全面. 看到网上一篇介绍webstrom的文章 ...

  5. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及abp封装的Javascript函数库

    经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这里算是前面几节的一个初次试水. 首先我们数据库已经有的相应的数据. 模型和DTO已经建好,所以我们直接在服务 ...

  6. JavaScript开发工具大全

    译者按: 最全的JavaScript开发工具列表,总有一款适合你! 原文: THE ULTIMATE LIST OF JAVASCRIPT TOOLS 译者: Fundebug 为了保证可读性,本文采 ...

  7. javaScript系列 [01]-javaScript函数基础

    [01]-javaScript函数基础 1.1 函数的创建和结构 函数的定义:函数是JavaScript的基础模块单元,包含一组语句,用于代码复用.信息隐蔽和组合调用. 函数的创建:在javaScri ...

  8. javascript常用工具类整理(copy)

    JavaScript常用工具类 类型 日期 数组 字符串 数字 网络请求 节点 存储 其他 1.类型 isString (o) { //是否字符串 return Object.prototype.to ...

  9. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及几种abp封装的Javascript函数库

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期         简介 经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这 ...

随机推荐

  1. PHP通用分页类

    Page.class.php <?php/** * 分页类 * * 调用方式: * $p=new Page(总条数,显示页数,当前页码,每页显示条数,[链接]); * print_r($p-&g ...

  2. 2019-2020-11 20199317 《Linux内核原理与分析》 第十一周作业

    ShellShock 攻击实验 1  ShellShock 简介      Shellshock,又称Bashdoor,是在Unix中广泛使用的Bash shell中的一个安全漏洞,首次于2014年9 ...

  3. PAT(甲级)2017年春季考试

    PAT(甲级)2017年春季考试 A.Raffle for Weibo Followers #include<bits/stdc++.h> using namespace std; int ...

  4. JavaScript的内存模型

    引言 在我们的前端日常工作中,无时无刻不在进行着变量的声明和赋值,你是否也曾碰到过变量声明报错或变量被污染的问题,如果你跟笔者一样碰到过,那么我们应该暂时停下来好好思考问题发生的原因以及如何采取相应的 ...

  5. python使用mysql的一些坑

    注意:如果你用的是python3.x,直接去看第四个问题 遇到的第一个问题 正常来说直接执行pip安装,就是可以的,但是MySQL-python偏偏比较独特 pip install MySQL-pyt ...

  6. redis位图巧用,节约内存

    最近要做一个圣诞抽奖活动,需要记录每天用户签到的记录,以前一般都是用普通的字符串数据类型,每个用户的签到用一个 key // 用户10在活动第一天的签到key为record:1:10 $key = & ...

  7. CodeForces1000A-Light It Up

    B. Light It Up time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  8. tensorflow处理mnist(一)

    这个文章是对google官方教程的解释 预备知识 神经网络卷积,神经网络原理 argmaxsum axis tensorflow里面有类似的函数,含义和numpy中的一样. tensorflow最基础 ...

  9. Day 05 文本处理和爬虫基础1

    目录 什么是文件 什么是文本 如何通过文本编辑器控制.txt文件 打开文件的三种模式 t和b模式 高级应用 文本处理 + 词云分析 效果如下 爬虫原理 requests模块 re模块 爬取图片 爬取视 ...

  10. 【React】345- React v16.9 新特性[译]

    今天我们发布了 React 16.9.它包含了一些新特性.bug修复以及新的弃用警告,以便与筹备接下来的主要版本. 一.新弃用 重命名 Unsafe 生命周期方法 一年前,我们宣布 unsafe 生命 ...