JavaScript工具函数

验证规则

验证邮箱

1
export const isEmail = (email) => {
2
  return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(email);
3
}

验证手机号码

1
export const isMobile = (phone) => {
2
  return /^1(3|4|5|6|7|8|9)\d{9}$/.test(phone);
3
}

验证电话号码

1
export const isTelPhone = (phone) => {
2
  return /^0\d{2,3}-?\d{7,8}$^/.test(phone);
3
}

判断是否是身份证号

1
export const isIdCard = (str) => {
2
	const reg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
3
	return reg.test(str);
4
}

判断是否中文

1
export const isChina = (str) => {
2
	const reg = /^[\\u4E00-\\u9FA5]{2,4}$/;
3
	return reg.test(str);
4
}

单位转化

将金额转化为带单位的字符串

1
export const formatterUnit = (value) => {
2
  return `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
3
}

将带单位的金额转化为数字

1
export const parserUnit = (value) => {
2
	return value.replace(/\$\s?|(,*)/g, '');
3
}

将单词转换为首字母大写

1
export const wordUpper = (word) => {
2
	return word.replace(word[0], word[0].toUpperCase());
3
}

对象

检查一个对象是否有子元素

1
export const hasChildren = (item = {}, keyname = "children") => {
2
	return item[keyname] && Array.isArray(item[keyname]) && item[keyname].length > 0
3
}

表单元素转化为对象

1
export const formToObject = (form) => {
2
	return Array.from(new FormData(form)).reduce((acc, [key, value]) => ({
3
		...acc,
4
		[key]: value
5
	}), {}, );
6
}

从给定的键值对创建对象

使用Array.reduce()创建和组合键值对

1
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
2
// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2}

Array

对象数组去重

1
export const removalArr = (arr) => {
2
	return [...new Set(arr.map(v => JSON.stringify(v)))].map(v => JSON.parse(v));
3
}

获取数组交集

1
export const intersection = (list, ...args) => {
2
	return list.filter(item => args.every(list => list.includes(item)));
3
}

分割指定长度的元素数组

1
export const listChunk = (list, size = 1, cacheList = []) => {
2
	const tmp = [...list];
3
	if (size <= 0) {
4
		return cacheList;
5
	}
6
	while (tmp.length) {
7
		cacheList.push(tmp.splice(0, size));
8
	}
9
	return cacheList;
10
}

返回数组中的最大值

Math.max()与扩展运算符 (...) 结合使用以获取数组中的最大值

1
const arrayMax = arr => Math.max(...arr);
2
// arrayMax([10, 1, 5]) -> 10

返回数组中的最小值

Math.min()与扩展运算符 (...) 结合使用以获取数组中的最小值

1
const arrayMin = arr => Math.min(...arr);
2
// arrayMin([10, 1, 5]) -> 1

将数组块划分为指定大小的较小数组

使用Array.from()创建新的数组, 这符合将生成的区块数。
使用Array.slice()将新数组的每个元素映射到size长度的区块。
如果原始数组不能均匀拆分, 则最终的块将包含剩余的元素。

1
const chunk = (arr, size) =>
2
Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size));
3
// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],[5]]

从数组中移除 falsey

使用Array.filter()筛选出 falsey 值 (falsenull0"""undefinedNaN).

1
const compact = (arr) => arr.filter(Boolean);
2
// compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ]

计算数组中值的出现次数

使用Array.reduce()在每次遇到数组中的特定值时递增计数器。

1
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
2
// countOccurrences([1,1,2,1,2,3], 1) -> 3

深拼合数组

使用递归。使用Array.concat()与空数组 ([]) 和跨页运算符 (...) 来拼合数组。递归拼合作为数组的每个元素。

1
const deepFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v));
2
// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5]

返回两个数组之间的差异

b创建Set , 然后使用Array.filter() on 只保留a b中不包含的值.

1
const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); };
2
// difference([1,2,3], [1,2,4]) -> [3]

返回数组的所有不同值

使用 ES6 Set...rest运算符放弃所有重复的值。

1
const distinctValuesOfArray = arr => [...new Set(arr)];
2
// distinctValuesOfArray([1,2,2,3,4,4,5]) -> [1,2,3,4,5]

移除数组中的元素, 直到传递的函数返回true。返回数组中的其余元素

在数组中循环, 使用Array.shift()将数组的第一个元素除去, 直到函数的返回值为true。返回其余元素。

1
const dropElements = (arr, func) => {
2
while (arr.length > 0 && !func(arr[0])) arr.shift();
3
return arr;
4
};
5
// dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4]

返回数组中的每个第 n 个元素

使用Array.filter()创建一个包含给定数组的每个第 n 个元素的新数组。

1
const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === 0);
2
// everyNth([1,2,3,4,5,6], 2) -> [ 1, 3, 5 ]

筛选出数组中的非唯一值。

对于只包含唯一值的数组, 请使用Array.filter()

1
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
2
// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5]

拼合数组

使用Array.reduce()获取数组中的所有元素和concat()以拼合它们。

1
const flatten = arr => arr.reduce((a, v) => a.concat(v), []);
2
// flatten([1,[2],3,4]) -> [1,2,3,4]

返回数组中的随机元素

使用Math.random()生成一个随机数, 将它与length相乘, 并使用数学将其舍入到最接近的整数Math.floor()
此方法也适用于字符串。

1
const sample = arr => arr[Math.floor(Math.random() * arr.length)];
2
// sample([3, 7, 9, 11]) -> 9

返回两个数组中都显示的元素的数组

使用filter()可删除不属于values的值, 使用includes()确定

1
const similarity = (arr, values) => arr.filter(v => values.includes(v));
2
// similarity([1,2,3], [1,2,4]) -> [1,2]

浏览器

如果页的底部可见, 则返回true , 否则为false

使用scrollYscrollHeightclientHeight来确定页面底部是否可见。

1
const bottomVisible = () =>
2
document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight;
3
// bottomVisible() -> true

是否微信浏览器

1
export const isWeiXin = () => {
2
  let ua = navigator.userAgent.toLowerCase();
3
  return ua.match(/microMessenger/i) == 'micromessenger'
4
}

是否移动端

1
export const isDeviceMobile = () => {
2
  let ua = navigator.userAgent.toLowerCase();
3
  return /android|webos|iphone|ipod|balckberry/i.test(ua)
4
}

是否ios

1
export const isIos = () => {
2
  let ua = navigator.userAgent.toLowerCase();
3
  return !!ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
4
}

是否Android

1
export const isAndroid = () => {
2
  return u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
3
}

是否PC

1
export const isPC = () => {
2
  var userAgentInfo = navigator.userAgent;
3
  var Agents = ["Android", "iPhone",
4
    "SymbianOS", "Windows Phone",
5
    "iPad", "iPod"
6
  ];
7
  var flag = true;
8
  for (var v = 0; v < Agents.length; v++) {
9
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
10
      flag = false;
11
      break;
12
    }
13
  }
14
  return flag;
15
}

获取url参数

1
export const getQueryString = (name) => {
2
  const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
3
  const search = window.location.search.split('?')[1] || '';
4
  const params = search.match(reg) || [];
5
  return params[2];
6
}

复制粘贴

1
export const copyTextToClipboard = (value) => {
2
  var textArea = document.createElement("textarea");
3
  textArea.style.background = 'transparent';
4
  textArea.value = value;
5
  document.body.appendChild(textArea);
6
  textArea.select();
7
  try {
8
    var successful = document.execCommand('copy');
9
  } catch (err) {
10
    console.log('Oops, unable to copy');
11
  }
12
  document.body.removeChild(textArea);
13
}

获取当前页面的滚动位置

1
export const getScrollPosition = (el = window) => {
2
	return {
3
		x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
4
		y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
5
	}
6
}

平滑滚动到页面顶部

1
export const scrollToTop = () => {
2
	const offset = document.documentElement.scrollTop || document.body.scrollTop;
3
	if (offset > 0) {
4
		window.requestAnimationFrame(scrollToTop);
5
		window.scrollTo(0, offset - offset / 8);
6
	}
7
}

如果指定的元素在视区中可见, 则返回true , 否则为false

使用Element.getBoundingClientRect()window.inner(Width|Height)值以确定给定元素在视区中是否可见。
省略第二个参数以确定该元素是否完全可见, 或指定true以确定它是否部分可见。

1
const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
2
const { top, left, bottom, right } = el.getBoundingClientRect();
3
return partiallyVisible
4
? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
5
((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
6
: top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
7
};
8
// e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10}
9
// elementIsVisibleInViewport(el) -> false (not fully visible)
10
// elementIsVisibleInViewport(el, true) -> true (partially visible)

返回一个包含当前 URL 参数的对象

使用match()与适当的正则表达式来获取所有键值对, Array.reduce()可将它们映射并合并到单个对象中。
location.search作为要应用于当前url的参数传递.

1
const getURLParameters = url =>
2
url.match(/([^?=&]+)(=([^&]*))/g).reduce(
3
(a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}
4
);
5
// getURLParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'}

日期

返回两个日期之间的差异 (以天为值)

1
const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24);
2
// getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9

将 JSON 对象转换为日期

使用Date(), 将 JSON 格式的日期转换为可读格式 (dd/mm/yyyy日)).

1
const JSONToDate = arr => {
2
const dt = new Date(parseInt(arr.toString().substr(6)));
3
return `${ dt.getDate() }/${ dt.getMonth() + 1 }/${ dt.getFullYear() }`
4
};
5
// JSONToDate(/Date(1489525200000)/) -> "14/3/2017"

将日期从美国格式转换为英文格式

Date.toISOString()split('T')replace()将日期从美式格式转换为英文格式。
如果传递的时间不能转换为日期, 则抛出错误。

1
const toEnglishDate  = (time) =>
2
{try{return new Date(time).toISOString().split('T')[0].replace(/-/g, '/')}catch(e){return}};
3
// toEnglishDate('09/21/2010') -> '21/09/2010'

功能

链异步函数

循环遍历包含异步事件的函数数组, 当每个异步事件完成时调用next

1
const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); };
2
/*
3
chainAsync([
4
  next => { console.log('0 seconds'); setTimeout(next, 1000); },
5
  next => { console.log('1 second');  setTimeout(next, 1000); },
6
  next => { console.log('2 seconds'); }
7
])
8
*/

数学

生成随机len位数字

1
export const randomLenNum = (len, date) => {
2
	let random = "";
3
	random = Math.ceil(Math.random() * 100000000000000)
4
		.toString().substr(0, len || 4);
5
	if (date) random = random + Date.now();
6
	return random;
7
}

小数位不够,用0补足位数

1
export const dealWithFun = (num, bit) => {
2
	const fixNum = parseFloat(num);
3
	if (isNaN(fixNum)) {
4
		return 0;
5
	}
6
	let str_x = num.toString(); // 为了后面值的拼接
7
	const point_decimal = fixNum.indexOf("."); // 取得小数点的下标key
8
	// 位数不足补0
9
	while (fixNum.length <= point_decimal.length + bit) {
10
		str_x += "0";
11
	}
12
	return str_x;
13
}

返回数字数组的平均值

使用Array.reduce()将每个值添加到累加器中, 并以0的值初始化, 除以数组的length

1
const arrayAverage = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length;
2
// arrayAverage([1,2,3]) -> 2

返回一个数字数组的总和

使用Array.reduce()将每个值添加到累加器中, 并以0值初始化.

1
const arraySum = arr => arr.reduce((acc, val) => acc + val, 0);
2
// arraySum([1,2,3,4]) -> 10

应用 Collatz 算法

如果n是偶数, 则返回n/2。否则返回3n+1.

1
const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1);
2
// collatz(8) --> 4
3
// collatz(5) --> 16

将数字转换为数字数组

将数字转换为字符串, 在 ES6 ([...string]) 中使用扩展运算符生成数组。
使用Array.map()parseInt()将每个值转换为整数

1
const digitize = n => [...''+n].map(i => parseInt(i));
2
// digitize(2334) -> [2, 3, 3, 4]

返回两点之间的距离

使用Math.hypot()计算两个点之间的欧氏距离。

1
const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0);
2
// distance(1,1, 2,3) -> 2.23606797749979

返回指定范围内的随机整数

使用Math.random()生成一个随机数并将其映射到所需的范围, 使用Math.floor()使其成为整数。

1
const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
2
// randomIntegerInRange(0, 5) -> 2

返回指定范围内的随机数

使用Math.random()生成随机值, 并使用乘法将其映射到所需的范围

1
const randomNumberInRange = (min, max) => Math.random() * (max - min) + min;
2
// randomNumberInRange(2,10) -> 6.0211363285087005

字符串

将字符串的第一个字母大写

1
const capitalize = ([first,...rest], lowerRest = false) =>
2
first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join(''));
3
// capitalize('myName') -> 'MyName'
4
// capitalize('myName', true) -> 'Myname'

将字符串中每个单词的首字母大写

使用replace()匹配每个单词和toUpperCase()的第一个字符以将其大写

1
const capitalizeEveryWord = str => str.replace(/b[a-z]/g, char => char.toUpperCase());
2
// capitalizeEveryWord('hello world!') -> 'Hello World!'

从匹配转换字符串

使用replace()可删除下划线、连字符和空格, 并将单词转换为匹配。省略第二个参数以使用默认分隔符_.

1
const fromCamelCase = (str, separator = '_') =>
2
str.replace(/([a-zd])([A-Z])/g, '$1' + separator + '$2')
3
.replace(/([A-Z]+)([A-Z][a-zd]+)/g, '$1' + separator + '$2').toLowerCase();
4
// fromCamelCase('someDatabaseFieldName', ' ') -> 'some database field name'
5
// fromCamelCase('someLabelThatNeedsToBeCamelized', '-') -> 'some-label-that-needs-to-be-camelized'
6
// fromCamelCase('someJavascriptProperty', '_') -> 'some_javascript_property'

反转字符串

使用数组 destructuringArray.reverse()可反转字符串中字符的顺序。使用join('')组合字符以获取字符串.

1
const reverseString = str => [...str].reverse().join('');
2
// reverseString('foobar') -> 'raboof'

按字母顺序对字符串中的字符进行排序

1
const sortCharactersInString = str =>
2
str.split('').sort((a, b) => a.localeCompare(b)).join('');
3
// sortCharactersInString('cabbage') -> 'aabbceg'

实用函数

isArray

检查给定参数是否为数组。

1
const isArray = val => !!val && Array.isArray(val);
2
// isArray(null) -> false
3
// isArray([1]) -> true

isBoolean

检查给定的参数是否为布尔元素。

1
const isBoolean = val => typeof val === 'boolean';
2
// isBoolean(null) -> false
3
// isBoolean(false) -> true

isFunction

检查给定参数是否为函数。

1
const isFunction = val => val && typeof val === 'function';
2
// isFunction('x') -> false
3
// isFunction(x => x) -> true

isNumber

检查给定参数是否为数字

1
const isNumber = val => typeof val === 'number';
2
// isNumber('1') -> false
3
// isNumber(1) -> true

isString

检查给定参数是否为字符串

1
const isString = val => typeof val === 'string';
2
// isString(10) -> false
3
// isString('10') -> true

isSymbol

检查给定参数是否为Symbol

1
const isSymbol = val => typeof val === 'symbol';
2
// isSymbol('x') -> false
3
// isSymbol(Symbol('x')) -> true

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!