已上传到npm官网,实例readme后期会逐渐完善!!!
npm i boys-utils
// JS中使用
import {
hiddenPhone
} from "boys-utils"
const phone = "13759940404"
console.log(hiddenPhone(phone));
1. 数组并集(ArrayUnion)
export const ArrayUnion = function (array1, array2, key) {
return array1.concat(array2.filter(i => (key ? !array1.map(i => i[key]).includes(i[key]) : !array1.includes(key))))
}
// 方法:
const Union = function (array1, array2, key) {
return array1.concat(array2.filter(i => (key ? !array1.map(i => i[key]).includes(i[key]) : !array1.includes(key))))
}
// 实例1:
let a = [1, 2, 3, 4, 5]
let b = [1, 2, 4, 5, 6]
union(a, b) // [1,2,3,4,5,6]
// 实例2:
let a1 = [
{ id: 1, name: '张三', age: 20 },
{ id: 2, name: '李四', age: 21 },
{ id: 3, name: '小二', age: 23 }
]
let b1 = [
{ id: 2, name: '李四', age: 21 },
{ id: 4, name: '小明', age: 24 },
{ id: 5, name: '小红', age: 25 }
]
// 通过 id 获取并集
union(a1, b1, 'id')
/*
[
{id: 1, name: "张三", age: 20}
{id: 2, name: "李四", age: 21}
{id: 3, name: "小二", age: 23}
{id: 4, name: "小明", age: 24}
{id: 5, name: "小红", age: 25}
]
*/
2. 数组交集(ArrayIntersection)
export const ArrayIntersection = function (a, b, k) {
return a.filter(t => (k ? b.map(i => i[k]).includes(t[k]) : b.includes(t)))
}
// 代码:
const Intersection = function (a, b, k) {
return a.filter(t => (k ? b.map(i => i[k]).includes(t[k]) : b.includes(t)))
}
// 实例1:
let a = [1, 2, 3, 4, 5]
let b = [1, 2, 4, 5, 6]
intersection(a, b) // [1,2,4,5]
// 实例2:
let a1 = [
{ id: 1, name: '张三', age: 20 },
{ id: 2, name: '李四', age: 21 },
{ id: 3, name: '小二', age: 23 }
]
let b1 = [
{ id: 2, name: '李四', age: 21 },
{ id: 4, name: '小明', age: 24 },
{ id: 5, name: '小红', age: 25 }
]
intersection(a1, b1, 'id') //[ { id: 2, name: '李四', age: 21 }]
3. 数组差集(ArrayExcept)
export const ArrayExcept = function (a, b, k) {
return [...a, ...b].filter(i => ![a, b].every(t => (k ? t.map(i => i[k]).includes(i[k]) : t.includes(i))))
}
// 代码:
const except = function (a, b, k) {
return [...a, ...b].filter(i => ![a, b].every(t => (k ? t.map(i => i[k]).includes(i[k]) : t.includes(i))))
}
// 实例1:
let a = [1, 2, 3, 4, 5]
let b = [1, 2, 4, 5, 6]
except(a, b) // [3,6]
// 实例2:
let a1 = [
{ id: 1, name: '张三', age: 20 },
{ id: 2, name: '李四', age: 21 },
{ id: 3, name: '小二', age: 23 }
]
let b1 = [
{ id: 2, name: '李四', age: 21 },
{ id: 4, name: '小明', age: 24 },
{ id: 5, name: '小红', age: 25 }
]
except(a1, b1, 'id')
/*
[
{id: 1, name: "张三", age: 20}
{id: 3, name: "小二", age: 23}
{id: 4, name: "小明", age: 24}
{id: 5, name: "小红", age: 25}
]
*/
4. 数组分组(ArrayGroup)
export const ArrayGroup = function (arr, num) {
return [...Array(Math.ceil(arr.length / num)).keys()].reduce((p, _, i) => (p.push(arr.slice(i * num, (i + 1) * num)), p), [])
}
// 代码:
/**
* @description: 一维数组转二维数组 (分组)
* @param {Array} arr:数组
* @param {Number} num: 平分基数(num 个为一组进行分组(归档))
*/
const group = function (arr, num) {
return [...Array(Math.ceil(arr.length / num)).keys()].reduce((p, _, i) => (p.push(arr.slice(i * num, (i + 1) * num)), p), [])
}
// 实例1:
group([1,2,3,4,5,6,7,8,9,10],2) // [[1,2],[3,4],[5,6],[7,8],[9,10]]
// 实例2:
group([1,2,3,4,5,6,7,8,9,10],3) // [[1,2,3],[4,5,6],[7,8,9],[10]]
5. 数组平均数(ArrayMean)
export const ArrayMean = function (a, f) {
return (f ? a.map(typeof f === 'function' ? f : v => v[f]) : a).reduce((acc, val) => acc + val * 1, 0) / a.length
}
// 代码:
/**
* 数组平均数
* @param {Array} a:数组
* @param {Function | String} f:函数 或 key
*/
const mean = function (a, f) {
return (f ? a.map(typeof f === 'function' ? f : v => v[f]) : a).reduce((acc, val) => acc + val * 1, 0) / a.length
}
// 实例1:
mean([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n) // 5
mean([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n') // 5
mean([4, 2, 8, 6]) // 5
mean(['4', 2, '8', 6]) // 5
6.数组生成(ArrayRange)
export const ArrayRange = function (min, max) {
return Array.from({
length: max - min + 1
}, (_, i) => i + min)
}
// 代码:
/**
* @description: 生成 起止数字间(包含起止数字)的升序数组
* @param {Number} min : 最小值
* @param {Number} max :最大值
*/
const range = function (min, max) {
return Array.from({ length: max - min + 1 }, (_, i) => i + min)
}
// 实例:
range(0,10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
range(1,9) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
7.数组求和(ArraySum)
export const ArraySum = function (a, k) {
return a.reduce((p, c) => p + (k ? c[k] || 0 : c), 0)
}
// 代码:
const sum = function (a, k) {
return a.reduce((p, c) => p + (k ? c[k] || 0 : c), 0)
}
// 实例:
let a = [1, 2, 3, 4, 5]
sum(a) // 15
let a1 = [
{ id: 1, name: '张三', age: 20 },
{ id: 2, name: '李四', age: 21 },
{ id: 3, name: '小二', age: 23 }
]
sum(a1, 'age') // 64
8.数组扁平化(ArrayFlatten)
export const ArrayFlatten = function (arr, depth = 1) {
return arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), [])
}
// 代码:
/**
* 指定深度扁平化数组
* @param {Array} arr :扁平化的数组
* @param {Number} depth:扁平化的层级
*/
const flatten = function (arr, depth = 1) {
return arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), [])
}
// 实例:
flatten([1, 2, 3, [4, [5, 6, [7]]]]) //[1, 2, 3, 4, [5,6,[7]]]
flatten([1, 2, 3, [4, [5, 6, [7]]]], 2) //[1, 2, 3, 4, 5,6,[7]]
9. 数组值位置交换(ArrayExchangePosition)
export const ArrayExchangePosition = function (arr, oldIndex, newIndex, isChangeOldArr = false) {
let a = isChangeOldArr ? arr : JSON.parse(JSON.stringify(arr))
a.splice(oldIndex, 1, a.splice(newIndex, 1, a[oldIndex])[0])
return a
}
// 代码:
/**
* @description: 交换数组中任一两个值的位置
* @param {Array} arr:数组
* @param {Number} oldIndex:老位置索引
* @param {Number} newIndex:新位置索引
* @param {Boolean} isChangeOldArr: 是否改变原数组
* @return {Array} 返回一个数组
*/
const exchangePostion = function (arr, oldIndex, newIndex, isChangeOldArr = false) {
let a = isChangeOldArr ? arr : JSON.parse(JSON.stringify(arr))
a.splice(oldIndex, 1, a.splice(newIndex, 1, a[oldIndex])[0])
return a
}
// 实例1:
let a1 = [1, 2, 3, 4, 5, 6]
exchangePostion(a1, 4, 1)// [1, 5, 3, 4, 2, 6]
a1 //[1, 2, 3, 4, 5, 6]
// 实例2:
let a1 = [1, 2, 3, 4, 5, 6]
exchangePostion(a1, 4, 1,true)// [1, 5, 3, 4, 2, 6]
a1 // [1, 5, 3, 4, 2, 6]
10.数组归档(归类)(ArrayArchive)
export const ArrayArchive = function (arr, key) {
return Array.from(new Set(arr.map(i => i[key]))).reduce((p, c) => (p.push(arr.filter(i => i[key] === c)), p), [])
}
// 代码:
/**
* @description: 对一维 json 数组进行归档(根据 key)
* @param {Array} arr:一维数组
* @param {String} key:key 字符串
*/
const archive = function (arr, key) {
return Array.from(new Set(arr.map(i => i[key]))).reduce((p, c) => (p.push(arr.filter(i => i[key] === c)), p), [])
}
// 实例:
let books = [ {date:'1月',name:'地理书'}, {date:'1月',name:'历史书'}, {date:'2月',name:'化学书'} ]
archive( books, 'date')
// [[{date:'1月',name:'地理书'},{date:'1月',name:'历史书'}],[ {date:'2月',name:'化学书'}]]
11. Array.includes判断多个if条件
//Longhand
if (x === 'abc' || x === 'def' || x === 'ghi' || x ==='jkl') {
//logic
}
//Shorthand 是否包含对应条件
if (['abc', 'def', 'ghi', 'jkl'].includes(x)) {
//logic
}
12. Array.find 查找符合条件的数组元素
const data = [
{
type: 'test1',
name: 'abc'
},
{
type: 'test2',
name: 'cde'
},
{
type: 'test1',
name: 'fgh'
},
]
function findtest1(name) {
for (let i = 0; i < data.length; ++i) {
if (data[i].type === 'test1' && data[i].name === name) {
return data[i];
}
}
}
//Shorthand
filteredData = data.find(data => data.type === 'test1' && data.name === 'fgh');
console.log(filteredData); // { type: 'test1', name: 'fgh' }
13.数组中所有项都满足某条件:Array.every
14. 数组中是否有某一项满足条件:Array.some
15. 还有 Array.find、Array.slice、Array.findIndex、Array.reduce、Array.splice 等,在实际场景中可以根据需要使用。
16. 真值判断简写
// Longhand
if (tmp === true) or if (tmp !== "") or if (tmp !== null)
// Shorthand
//it will check empty string,null and undefined too
if (test1)
特别需要注意tmp=0或者tmp='0' 都是false。
17. 多条件的 && 运算符,调用函数
//Longhand
if (test1) {
callMethod();
}
//Shorthand
test1 && callMethod(); // 简写,满足要求调用函数~
18. 三元运算符实现短函数调用
// Longhand
function test1() {
console.log('test1');
};
function test2() {
console.log('test2');
};
var test3 = 1;
if (test3 == 1) {
test1();
} else {
test2();
}
// Shorthand
(test3 === 1? test1:test2)(); // 简写:方法调用
19. 对象属性解构简写
let test1 = 'a';
let test2 = 'b';
//Longhand
let obj = {test1: test1, test2: test2};
//Shorthand 相同的名称才可以简写哦
let obj = {test1, test2};
20.比较大小使用 a - b > 0的方式更好,用a > b有时候会出现错误
错误用法
'20' > '100' // true
预期结果
'20' - '100' > 0 // false
//数组排序算法
arr.sort((a, b ) =>{
return a-b
})
对象形式的排序:
let arr = [{title:'A'},{title:'C'},{title:'B'}]
function SortArrByKeyCode(obj, key) {
return obj.sort((a, b) => {
return a[key].charCodeAt(0) - b[key].charCodeAt(0)
})
}
SortArrByKeyCode(arr,'title'); // [{title:'A'},{title:'B'},{title:'C'}]
21.链式取值a[0].b不存在的undefined 问题(推荐loadsh库的方法,可以直接复制方法)
1. 采用ES6中的 链式操作符 ?. 可直接解决问题
https://liyangtao.blog.csdn.net/article/details/105675777
//开发中,链式取值是非常正常的操作,如:
res.data.goods.list[0].price
// 一般的解决方案:(过长的话会比较糅杂了)
if (res.data.goods.list[0] && res.data.goods.list[0].price) {
// your code
}
如果再精细一点,对于所有都进行校验的话,就会像这样:
if (res && res.data && res.data.goods && res.data.goods.list && res.data.goods.list[0] && res.data.goods.list[0].price){
// your code
}
2. 以前的方式,通过loadsh库的方法
// 解决方案完结版:
1. 通过函数解析字符串(lodash的 _.get 方法)下面是get方法:
// _.get(object, path, [defaultValue]) 随后一个参数是取值为undefined时候的默认值
function get (obj, props, def) {
if((obj == null) || obj == null || typeof props !== 'string') return def;
const temp = props.split('.');
const fieldArr = [].concat(temp);
temp.forEach((e, i) => {
if(/^(\w+)\[(\w+)\]$/.test(e)) {
const matchs = e.match(/^(\w+)\[(\w+)\]$/);
const field1 = matchs[1];
const field2 = matchs[2];
const index = fieldArr.indexOf(e);
fieldArr.splice(index, 1, field1, field2);
}
})
return fieldArr.reduce((pre, cur) => {
const target = pre[cur] || def;
if(target instanceof Array) {
return [].concat(target);
}
if(target instanceof Object) {
return Object.assign({}, target)
}
return target;
}, obj)
}
// 例子1:
var object = { a: [{ b: { c: 3 } }] };
var result = _.get(object, 'a[0].b.c', 1);
console.log(result); // 3
// 例子2:
var c = {
a: {
b : [1,2,3]
}
}
_get(c ,'a.b') // [1,2,3]
_get(c, 'a.b[1]') // 2
_get(c, 'a.d', 12) // 12
2. 使用解构赋值
const obj = {
a:{
b: [1,2,3,4]
},
a1: 121,
a2: 'name'
}
let {a: result} = obj // result : {b: [1,2,3,4]}
let {a1: result} = obj // result: 121
let {b: result} = obj // result: undefined
当然,这个时候为了保证不报undefined,我们仍然需要定义默认值,
let {b: result = 'default'} = obj // result: 'default'
3. 使用Proxy
function pointer(obj, path = []) {
return new Proxy(() => {}, {
get (target, property) {
return pointer(obj, path.concat(property))
},
apply (target, self, args) {
let val = obj;
let parent;
for(let i = 0; i < path.length; i++) {
if(val === null || val === undefined) break;
parent = val;
val = val[path[i]]
}
if(val === null || val === undefined) {
val = args[0]
}
return val;
}
})
}
使用方法:
var c = {
a: {
b : [1,2,3]
}
}
pointer(c).a(); // {b: [1,2,3]}
pointer(c).a.b(); // [1,2,3]
pointer(d).a.b.d('default value'); // default value
22. string强制转换为数字
// 方法1: 用*1(乘以1)来转化为数字(
// 步骤: 1. 用*1(乘以1)来转化为数字(实际上是调用.valueOf方法)
// 步骤: 2. 使用Number.isNaN来判断是否为NaN,或者使用 a !== a 来判断是否为NaN,因为 NaN !== NaN
'32' * 1 // 32
'ds' * 1 // NaN
null * 1 // 0
undefined * 1 // NaN
1 * { valueOf: ()=>'3' } // 3
// 方法2 : 常用:也可以使用+来转化字符串为数字
+ '123' // 123
+ 'ds' // NaN
+ '' // 0
+ null // 0
+ undefined // NaN
+ { valueOf: ()=>'3' } // 3
23.使用filter过滤数组中的所有假值(ArrayFilterFalse)
// 假值:false,null,0,"",undefined,NaN
const compact = arr => arr.filter(Boolean)
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]) // [ 1, 2, 3, 'a', 's', 34 ]
24.使用map将字符串形式的数字转换为数字形式的数组(ArrayStrToNum)
let strArr = ['1','2','3','4','5'];
let numArr = strArr.map(Number); // [1,2,3,4,5]
25. 取整( | 0 )
// 对一个数字| 0可以取整,负数也同样适用,num | 0
// 舍入取整 无论是否到5,均舍去
1.3 | 0 // 1
-1.9 | 0 // -1
// 进1取整: 无论是否到5,均进1
1.34 | 1 // 2
1.35 | 1 // 2
-1.4 | 1 // 1
-1.5 | 1 // 1
26. 判断奇偶数 (& 1)
// 对一个数字& 1可以判断奇偶数,负数也同样适用,num & 1
// 奇数为true,偶数为false
const num=3;
方式1:
!!(num & 1) // true
方式2:
!!(num % 2) // true
27. 函数: 函数默认值
func = (x, m = 3, n = 4 ) => (x * m * n); ===> func = (x, m = 3, n = 4 ) => { return x * m * n};
func(2) //output: 24
func(null) //output: 0 因为1*null = 0
28. 函数: 强制传参数,缺失报错
logError = ( ) => {
throw new Error('Missing parameter!');
}
foo = (bar = logError( ) ) => bar // 这里如果不传入参数,就会执行logError 函数报出错误
29. 箭头函数隐式返回值
// 1. 只有一个语句的箭头函数,可以隐式返回结果(函数必须省略大括号{ },以便省略返回关键字 return)。
// 2. 要返回多行语句(例如对象文本),需要使用( )而不是{ }来包裹函数体。这样可以确保代码以单个语句的形式进行求值。
function calcCircumference(diameter) {
return Math.PI * diameter
}
// 简写为:
calcCircumference = diameter => (Math.PI * diameter;)
比如省略()的情况:
calcCircumference = diameter => diameter; // 单个语句可以直接写
30.字符串: 拼接
1.字符串拼接用join(),避免使用+或+=的方式拼接较长的字符串
2.应使用数组保存字符串片段,使用时调用join方法。避免使用+或+=的方式拼接较长的字符串
3.过多的内存片段会影响性能
31. 时间字符串比较(时间形式注意补0)
// 字符串比较大小是按照字符串从左到右每个字符的charCode来的,但所以特别要注意时间形式注意补0
var a = "2014-08-08";
var b = "2014-09-09";
console.log(a>b, a<b); // false true
console.log("21:00"<"09:10"); // false
console.log("21:00"<"9:10"); // true 时间形式注意补0
32.数字:精确到指定位数的小数(NumberRound)
// 1. 将数字四舍五入到指定的小数位数。使用 Math.round() 和模板字面量将数字四舍五入为指定的小数位数。
// 2. 省略第二个参数 decimals ,数字将被四舍五入到一个整数。
const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`)
round(1.345, 2) // 1.35 Number(1.345e2e-2)
round(1.345, 1) // 1.3
round(1.345) // 1
33.数字补0操作(时间格式化的前置加0)(StringAddZero)
// 比如显示时间的时候有时候会需要把一位数字显示成两位
1.
const addZero1 = (num, len = 2) => (`0${num}`).slice(-len) // 从字符串倒数第len处开始截取到最后
2.
const addZero2 = (num, len = 2) => (`${num}`).padStart( len , '0') // padStart为ES6的字符串拼接方法
3.
const addZero3 = n => { n = n.toString(); return n[1] ? n : '0' + n }
addZero1(3) // 03
addZero2(32,4) // 0032
addZero3(6,2) // "06"
34.数组:统计数组中相同项的个数(ArrayEqualTotal)
// 使用reduce方法处理
//
var cars = ['BMW','Benz', 'Benz', 'Tesla', 'BMW', 'Toyota'];
var carsObj = cars.reduce(function (obj, name) {
obj[name] = obj[name] ? ++obj[name] : 1; // obj[name]存在就加一,不存在就为1
return obj;
}, {});
carsObj; // => { BMW: 2, Benz: 2, Tesla: 1, Toyota: 1 }
35.交换参数数值(解构最简单)
// es6方法:
let param1 = 1;
let param2 = 2;
[param1, param2] = [param2, param1]; // 2 , 1
// 或者: 一般方法
var temp = a; a = b; b = temp
b = [a, a = b][0]
a = a + b; b = a - b; a = a - b
36.批量接收多个请求返回结果
// 我们从/post中获取一个帖子,然后在/comments中获取相关评论
// 使用的是async/await,函数把返回值放在一个数组中
// 使用数组解构后就可以把返回值直接赋给相应的变量
async function getFullPost(){
return await Promise.all([
fetch('/post'),
fetch('/comments')
]);
}
const [post, comments] = getFullPost();
37.将数组平铺到指定深度()
// 1. 采用数组方法flat(),最多深度为1层
let a1 = [{a:1},{a:2},[{a:3},{a:4},[{a:5}]]]
a1.flat() // [{a:1},{a:2},{a:3},{a:4},[{a:5}]]
// 2. 使用递归,为每个深度级别 depth 递减 1 .
// 使用 Array.reduce() 和 Array.concat() 来合并元素或数组
// 省略第二个参数,depth 只能平铺到 1 (单层平铺) 的深度。 即和flat相同
const flatten = (arr, depth = 1) => depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), []) : arr.reduce((a, v) => a.concat(v), []);
flatten([1, [2,3, [7,8]], 3, 4]); // [1, 2, 3,[7,8],3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
38.对象数组按照某个属性查询最大值或最小值
var array=[
{
"index_id": 119,
"area_id": "18335623",
"name": "满意度",
"value": "100"
},
{
"index_id": 119,
"area_id": "18335624",
"name": "满意度",
"value": "20"
},
{
"index_id": 119,
"area_id": "18335625",
"name": "满意度",
"value": "80"
}];
// 一行代码搞定
最大值: Math.max.apply(Math, array.map(function(o) {return o.value}))
最小值: Math.min.apply(Math, array.map(function(o) {return o.value}))
执行以上一行代码可返还所要查询的array数组中对象value属性的最大值100;最小值为 20.
39.使用解构删除对象某个属性
let {_internal, tooBig, ...cleanObject} = {el1: '1', _internal:"secret", tooBig:{}, el2: '2', el3: '3'};
console.log(cleanObject); // {el1: '1', el2: '2', el3: '3'}
40.Object:Object [key] 实现表单验证
// object validation rules
const schema = {
first: {
required:true
},
last: {
required:true
}
}
// universal validation function
const validate = (schema, values) => {
for(field in schema) {
if(schema[field].required) {
if(!values[field]) {
return false;
}
}
}
return true;
}
console.log(validate(schema, {first:'Bruce'})); // false
console.log(validate(schema, {first:'Bruce',last:'Wayne'})); // true
41. 日期格式化方法
const formatTime = (date = new Date()) => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : `0${n}`
}
42. 日期格式化方法2
let months = {
Jan: { en: 'January', cn: '一' },
Feb: { en: 'February', cn: '二' },
Mar: { en: 'March', cn: '三' },
Apr: { en: 'April', cn: '四' },
May: { en: 'May', cn: '五' },
Jun: { en: 'June', cn: '六' },
Jul: { en: 'July', cn: '七' },
Aug: { en: 'August', cn: '八' },
Sep: { en: 'September', cn: '九' },
Oct: { en: 'Octorber', cn: '十' },
Nov: { en: 'November', cn: '十一' },
Dec: { en: 'December', cn: '十二' }
};
let weeks = {
Mon: { en: 'Monday', cn: '一' },
Tue: { en: 'Tuesday', cn: '二' },
Wed: { en: 'Wednesday', cn: '三' },
Thu: { en: 'Thursday', cn: '四' },
Fri: { en: 'Friday', cn: '五' },
Sat: { en: 'SaturDay', cn: '六' },
Sun: { en: 'Sunday', cn: '日' },
};
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
// const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
const timeDiff = (first, end) => {
let diff;
diff = end - first;
return diff
}
function FormatDate(strTime, style) {
if (!strTime) return "";
var date = new Date(strTime);
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var hour = date.getHours();
var minutes = date.getMinutes();
var seconds = date.getSeconds();
var weekday = date.getDay();
var week_day = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
if (month < 10) {
month = "0" + month;
}
if (day < 10) {
day = "0" + day;
}
if (hour < 10) {
hour = "0" + hour;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
if (style == 'week') { //返回星期格式
return month + "月" + day + "日 " + week_day[weekday];
} else if (style == 'simple') {
return year + "-" + month + "-" + day;
} else if (style == 'minutes') {
return year + "-" + month + "-" + day + " " + hour + ":" + minutes;
} else if (style == 'month') {
return month + "-" + day + " " + hour + ":" + minutes;
} else if (style == 'day') {
return year + "-" + month + "-" + day;
} else {
return year + "-" + month + "-" + day + " " + hour + ":" + minutes + ":" + seconds;
}
}
function dateFormat(date, format) {
if (!date)
return '';
format = format || 'Y-m-d';
let _date = new Date(date);
let [year, month, day, weekDay, hours, minutes, seconds] = [_date.getFullYear() + '', (_date.getMonth() + 1) + '', _date.getDate() + '', _date.getDay() + '', _date.getHours() + '', _date.getMinutes() + '', _date.getSeconds() + '']
let [monthEn, weekEn] = [_date.toUTCString().substr(8, 3), _date.toUTCString().substr(0, 3)];
let weekDay_ISO8601 = (weekDay === '0') ? '7' : weekDay;
return format.replace(/Y/g, year)//1970
.replace(/y/g, year.slice(-2))//70
.replace(/m/g, ('0' + month).slice(-2))//09
.replace(/n/g, month)//9
.replace(/M/g, monthEn)//Sep
.replace(/F/g, months[monthEn].en)//September
.replace(/\_F/g, months[monthEn].cn)//九
.replace(/j/g, day)//9
.replace(/d/g, ('0' + day).slice(-2))//09
.replace(/D/g, weekEn)//Sun
.replace(/l/g, weeks[weekEn].en)//Sunday
.replace(/_l/g, weeks[weekEn].cn)//日
.replace(/w/g, weekDay)//0
.replace(/N/g, weekDay_ISO8601)//7
.replace(/H/g, ('0' + hours).slice(-2))//06
.replace(/G/g, hours)//6
.replace(/i/g, ('0' + minutes).slice(-2))//06
.replace(/s/g, ('0' + seconds).slice(-2));//06
}
43.处理参数空值的情况(empty方法)(empty)
function empty(input) {
return (typeof input == 'undefined' || !input || /^\s*(null|0|undefined|false|no)\s*$/i.test(input) || (input instanceof Array && !input.length) || (typeof input == 'object' && ((!Object.keys(input).length) || (('length' in input) && !input.length))));
}
// 使用的话:
if(!empty(params)) { 如果非空则进行相应的处理! }
44.判断对象中是否存在指定的key(键名/属性名)(hasOwnerProperty)
判断API: in / hasOwnProperty
1、in :key是不是能访问?
只要在对象中可以访问到key,key in obj 总会返回true
这就包括两种情况:
(1)自身实例包含key属性
(2)原型对象上存在key属性
2、hasOwnProperty:key是否是自身的?
必须是自身实例包含key属性,才会返回true
obj.hasOwnProperty(key) // true
3、由此可以封装出函数去判断:
key是否是原型对象上的?
function hasPrototypeProperty(obj,key){
return !obj.hasOwnProperty(key)&&(key in obj)
}
本身是否包含key:
function hasOwnerProperty(obj,key){
return obj.hasOwnProperty(key)
}
45.防抖函数和节流函数(debounce / throttle)
<!--对于resize、scroll、mousemove这些持续触发的事件,并不希望在事件持续触发的过程中那么频繁的去执行函数;-->
函数的定义:
防抖:就是在函数触发事件后的n秒内函数只执行一次,如果在n秒内又触发了事件,则会重新计算函数执行的时间!
节流:就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率
应用场景:
防抖:输入框搜索自动补全事件,频繁操作点赞和取消点赞等等
节流:一般是用于resize、scroll、mousemove这些持续触发的事件
函数本体如下:
// 防抖函数:当一直调用函数时,要运行的代码块不会执行,直到停止操作!
function debounce(fn, delay = 500) {
var timer;
return function () {
var _this = this; // 当前函数的this
var args = arguments; // 实参,数组形式
if (timer) { // 再次触发时,清除掉上一次的定时器重新调用对应的函数;
clearTimeout(timer); //关键点
}
timer = setTimeout(function () { // 定时器函数
fn.apply(_this, args); // 这里是将自定义的函数指向到当前函数
}, delay)
}
}
简洁版防抖函数:
// 第一种
function debounceEasy(fn,delay = 500) {
let timer = null;
return function() {
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(()=>{
fn.apply(this,arguments)
timer = null;
}, delay)
}
}
// 第二种
export const debounce = (() => {
let timer = null
return (callback, wait = 800) => {
timer&&clearTimeout(timer)
timer = setTimeout(callback, wait)
}
})()
// 节流函数:频繁调用函数时,期间只会在定时器固定时间内执行对应的函数!
function throttle(fn, delay = 500) {
let timer;
return function () {
var _this = this;
var args = arguments;
if (timer) { // 当定时器存在就直接返回,知道当前事件执行完毕!
return; // 关键点
}
timer = setTimeout(function () {
fn.apply(_this, args)
timer = null // 关键点 这里是当对应函数执行后,将timer赋值为空,以便下次定时器事件重新开始
}, delay)
}
}
let num = 1;
function count() {
console.log(num++);
};
document.onmousemove = throttle(count, 1000)
简洁版节流函数:用于滚动条监听、鼠标移动事件
// 第一种
function throttle(fn,delay = 200) {
let timer = null;
return function(){
if(timer) { // 和防抖唯一不同的地方就是这里如果含有定时器不清除
return
}
timer = setTimeout(()=>{
fn.apply(this,arguments)
timer = null;
})
}
}
// 第二种
export const throttle = (() => {
let last = 0
return (callback, wait = 800) => {
let now = +new Date()
if (now - last > wait) {
callback()
last = now
}
}
})()
46. 获取网址的url参数并获取值,解析URL参数(URLGetParams)
let url = '?name=cocoli&age=20&height=180'
方式一:无参数则将当前url获取,填写就是返回指定字段值
function query(name) {
var str = location.search.substr(1); //获取url中"?"符后的字串
var theRequest = new Object();
strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
if(strs[i].split("=")[0] === name){
return unescape(strs[i].split("=")[1])
}else {
theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
}
}
return theRequest
}
var $name = query('name'); // 'cocoli'
query() // {name:cocoli,age:20,height:180}
方式二:URLSearchParams兼容性不是太高
function query(name) {
const search = location.search;
const param = new URLSearchParams(search);
return param.get(name)
}
query(name) // 'cocoli'
function querytoObj() { //无参,直接返回所有参数对象
const res = new Object();
const searchList = new URLSearchParams(location.search)
searchList.forEach((val, key) => {
res[key] = val
})
return res
}
querytoObj() // {name:cocoli,age:20,height:180}
方式三:正则表达式
function expQuery(name) {
const search = location.search.substr(1);
// 'name=cocoli&age=20&height=180'
const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`,'i')
const res = search.match(reg);
if(res === null ) {return null}
return res[2]
}
query('name')
方式四:replace
例子:goole.com?search=easy&page=3
const getParameters = (URL) => {
URL = JSON.parse(
'{"' +
decodeURI(URL.split("?")[1])
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"') +
'"}'
);
return JSON.stringify(URL);
};
getParameters(window.location);
// Result: { search : "easy", page : 3 }
方式五:URLSearchParams简易写法
例子:goole.com?search=easy&page=3
Object.fromEntries(new URLSearchParams(window.location.search))
// Result: { search : "easy", page : 3 }
47.金额大小写转换:暂支持数字转汉字大写(NumberMoneyConvert)
// 说明,代码默认不支持四位小数的四拾伍入,如果想直接四舍五入,可加上字符串round!
//代码如下所示:
function convertCurrency(money, flag = '') {
//汉字的数字
var cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
//基本单位
var cnIntRadice = new Array('', '拾', '佰', '仟');
//对应整数部分扩展单位
var cnIntUnits = new Array('', '万', '亿', '兆');
//对应小数部分单位
var cnDecUnits = new Array('角', '分', '毫', '厘');
//整数金额时后面跟的字符
var cnInteger = '整';
//整型完以后的单位
var cnIntLast = '元';
//最大处理的数字
var maxNum = 999999999999999.9999;
//金额整数部分
var integerNum;
//金额小数部分
var decimalNum;
//输出的中文金额字符串
var chineseStr = '';
//分离金额后用的数组,预定义
var parts;
if (money == '') {
return '';
}
money = parseFloat(money);
// 针对小数四位的保留,自动四舍五入. 1.01246 ~ 1.0125
if(flag == 'round') {
money = parseFloat(money).toFixed(4);
}
if (money >= maxNum) {
//超出最大处理数字
return '';
}
if (money == 0) {
chineseStr = cnNums[0] + cnIntLast + cnInteger;
return chineseStr;
}
//转换为字符串
money = money.toString();
if (money.indexOf('.') == -1) {
integerNum = money;
decimalNum = '';
} else {
// 分隔整数和小数部分
integerNum = parts[0];
decimalNum = parts[1].substr(0, 4);
if(flag == 'round') {
decimalNum = parts[1]
}
}
//获取整型部分转换
if (parseInt(integerNum, 10) > 0) {
var zeroCount = 0;
var IntLen = integerNum.length;
for (var i = 0; i < IntLen; i++) {
var n = integerNum.substr(i, 1);
var p = IntLen - i - 1;
var q = p / 4;
var m = p % 4;
if (n == '0') {
zeroCount++;
} else {
if (zeroCount > 0) {
chineseStr += cnNums[0];
}
//归零
zeroCount = 0;
chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
}
if (m == 0 && zeroCount < 4) {
chineseStr += cnIntUnits[q];
}
}
chineseStr += cnIntLast;
}
//小数部分
if (decimalNum != '') {
var decLen = decimalNum.length;
for (var i = 0; i < decLen; i++) {
var n = decimalNum.substr(i, 1);
if (n != '0') {
chineseStr += cnNums[Number(n)] + cnDecUnits[i];
}
}
}
if (chineseStr == '') {
chineseStr += cnNums[0] + cnIntLast + cnInteger;
} else if (decimalNum == '') {
chineseStr += cnInteger;
}
return chineseStr;
}
48.返回指定月份的天数(DateGetMonthDays)
方案1:
function getMonthCountDay (year, month) {
switch (month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31
case 4:
case 6:
case 9:
case 11:
return 30
case 2:
return year%400==0?(29):(year%4!=0||year%100==0?28:29)
}
}
方案2:借助 Date API 处理日期溢出特性(进位)
function getMonthCountDay (year, month) {
return 32 - new Date(year, month-1, 32).getDate()
}
方案3:借助 Date API 处理日期溢出特性(退位方案)
function getMonthCountDay (year, month) {
return new Date(year, month, 0).getDate()
}
example1:
[[2000,2],[2000,1],[2000,3],[2000,4],[2100,2],[2100,1],[2100,3],[2100,4],[2104,2],[2104,1],[2104,3],[2104,4],[2105,2],[2105,1],[2105,3],[2105,4],].map(v=>`${getMonthCountDay.apply(null,v)}天`)
// ["29天", "31天", "31天", "30天", "28天", "31天", "31天", "30天", "29天", "31天", "31天", "30天", "28天", "31天", "31天", "30天"]
常用调用:
let oneMonthDays = getMonthCountDay(2021,02)
console.log(oneMonthDays)
49. 获取浏览器Cookie的值(CookieSetValue / CookieGetValue / CookieRemoveValue / CookieClearValue )
const cookie = name => `; ${document.cookie}`.split(`; ${name}=`).pop().split(';').shift();
cookie('_ga');
// Result: "GA1.2.1929736587.1601974046"
//设置cookie的值,以及过期时间
function setCookie(cname,cvalue,exdays){
var d = new Date();
d.setTime(d.getTime()+(exdays*24*60*60*1000));
var expires = "expires="+d.toGMTString();
document.cookie = cname+"="+cvalue+"; "+expires;
}
//得到cookie的值
function getCookie(cname){
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }
}
return "";
}
//删除指定cookie的值
function removeCookie(cname){
var name = cname + "=";
var ca = document.cookie.split(';');
var cookieStr="";
for(var i=0; i<ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name)==0) {
document.cookie =c + ';expires=' + new Date(0).toUTCString()
}else{
cookieStr+=c;
cookieStr+=";";
}
document.cookie =cookieStr;
}
}
//删除全部的cookie值
function clearCookie(){
var keys=document.cookie.match(/[^ =;]+(?=\=)/g);
if (keys) {
for (var i = keys.length; i--;) ;
document.cookie=keys[i]+'=0;expires=' + new Date( 0).toUTCString() ;
}
}
50. 颜色RGB转十六进制(ColorRgbToHex)
// 颜色RGB转十六进制
const rgbToHex = (r, g, b) => "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
rgbToHex(0, 51, 255);
// Result: #0033ff
51. 复制到剪贴板(Copy)
const copyToClipboard = (text) => navigator.clipboard.writeText(text);
copyToClipboard("Hello World");
52. 查找日期位于一年中的第几天(dayOfYear)
const dayOfYear = (date) => Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);
dayOfYear(new Date());
// Result: 272
53. 英文字符串首字母大写
const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1)
capitalize("follow for more")
// Result: Follow for more
54. 计算2个日期之间相差多少天(DateDiffer)
const dayDif = (date1, date2) => Math.ceil(Math.abs(date1.getTime() - date2.getTime()) / 86400000)
dayDif(new Date("2020-10-21"), new Date("2021-10-22"))
// Result: 366
55. 清除全部Cookie(CookieClearValue)
// 清除全部Cookie
const clearCookies = document.cookie.split(';').forEach(cookie => document.cookie = cookie.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`));
clearCookies(); // 即可清除掉所有cookies
56. 生成随机十六进制颜色(ColorRandomHex)
// 可以使用 Math.random 和 padEnd 属性生成随机的十六进制颜色。
const randomHex = () => `#${Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0")}`;
console.log(randomHex());
// Result: #92b008
57. 打乱数组(ArrayShuffle)
// 可以使用sort 和 random 方法打乱数组
const shuffleArray = (arr) => arr.sort(() => 0.5 - Math.random());
console.log(shuffleArray([1, 2, 3, 4]));
// Result: [ 1, 4, 3, 2 ]
58. 检查用户的设备是否处于暗模式
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
console.log(isDarkMode)
// Result: True or False
60. 验证手机号(IsPhone)
export function mobilePhone(phone) {
if (isNull(phone)) {
return false
}
return /^1[3|4|5|6|7|8|9][0-9]\d{8}$/.test(phone)
}
61. 手机号脱敏(hiddenPhone)
// 手机号脱敏
// 第一种
export function hiddenPhone(telephone) {
console.warn('手机号脱敏:',telephone);
if (!isNull(telephone)) {
const prefix = telephone.slice(0, 3);
const suffix = telephone.slice(7, 11);
return prefix + '****' + suffix;
} else {
return "";
}
}
// 第二种
export const hideMobile = (mobile) => {
return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
}
62. 身份证脱敏(hiddenCarNo)
//银行卡号脱敏 身份证
export function hiddenCarNo(carNo, start, end) {
if (!isNull(carNo)) {
if (start == 0) {
var num = '***************'
var end = carNo.slice(carNo.length - end, carNo.length)
return num + ' ' + end
} else {
var first = carNo.slice(0, start)
var end = carNo.slice(carNo.length - end, carNo.length)
var center = ' ******** '
// for (var i = 0; i < carNo.length - start; i++) {
// center += '*'
// }
return first + ' ' + center + ' ' + end
}
}
return ''
}
63. 只包含数字和小数点(RegExpNumAndPoint)
//++++++++ 只包含数字和小数点
export function moneyParseFloat(srt) {
var pattern = /^\d+(\.\d+)?$/;
var result = pattern.exec(srt) //match 是匹配的意思 用正则表达式来匹配
if (result) {
return false
} else {
return true
}
}
64. 获取時間比如2022-2-2510:56:09(DateGetCurrentTime)
// 获取当前时间带时分秒
export function getCurrentDateHMS() {
let curr_date = new Date()
let currentDate =
curr_date.getFullYear() +
'-' +
(curr_date.getMonth() + 1) +
'-' +
curr_date.getDate() +
' ' +
curr_date.getHours() +
':' +
curr_date.getMinutes() +
':' +
curr_date.getSeconds() +
''
return currentDate
}
65. 阿拉伯数字转成大写
capitalAmount(123342342) // '壹亿贰仟叁佰叁拾肆万贰仟叁佰肆拾贰元整'
// 阿拉伯数字转换为中文大写
export function capitalAmount(amount) {
// 汉字的数字
const cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
// 基本单位
const cnIntRadice = ['', '拾', '佰', '仟']
// 对应整数部分扩展单位
const cnIntUnits = ['', '万', '亿', '兆']
// 对应小数部分单位
const cnDecUnits = ['角', '分', '毫', '厘']
// 整数金额时后面跟的字符
const cnInteger = '整'
// 整型完以后的单位
const cnIntLast = '元'
// 最大处理的数字
const maxNum = 9999999999999999.99
// 金额整数部分
let integerNum
// 金额小数部分
let decimalNum
// 输出的中文金额字符串
let chineseStr = ''
// 分离金额后用的数组,预定义
let parts
if (amount === '') {
return ''
}
amount = parseFloat(amount)
if (amount >= maxNum) {
// 超出最大处理数字
return ''
}
if (amount === 0) {
chineseStr = cnNums[0] + cnIntLast + cnInteger
return chineseStr
}
// 转换为字符串
amount = amount.toString()
if (amount.indexOf('.') === -1) {
integerNum = amount
decimalNum = ''
} else {
parts = amount.split('.')
integerNum = parts[0]
decimalNum = parts[1].substr(0, 4)
}
// 获取整型部分转换
if (parseInt(integerNum, 10) > 0) {
let zeroCount = 0
const IntLen = integerNum.length
for (let i = 0; i < IntLen; i++) {
const n = integerNum.substr(i, 1)
const p = IntLen - i - 1
const q = p / 4
const m = p % 4
if (n === '0') {
zeroCount++
} else {
if (zeroCount > 0) {
chineseStr += cnNums[0]
}
// 归零
zeroCount = 0
chineseStr += cnNums[parseInt(n, 10)] + cnIntRadice[m]
}
if (m === 0 && zeroCount < 4) {
chineseStr += cnIntUnits[q]
}
}
chineseStr += cnIntLast
}
// 小数部分
if (decimalNum !== '') {
const decLen = decimalNum.length
for (let i = 0; i < decLen; i++) {
const n = decimalNum.substr(i, 1)
if (n !== '0') {
chineseStr += cnNums[Number(n)] + cnDecUnits[i]
}
}
}
if (chineseStr === '') {
chineseStr += cnNums[0] + cnIntLast + cnInteger
} else if (decimalNum === '') {
chineseStr += cnInteger
}
return chineseStr
}
66. 金额格式化,处理添加数字金额千分位(推荐第一种最后一种) (NumberThousand)
--------------------------------------------------
NumberThousand(23124444.4483,2) // '23,124,444.45'
NumberThousand(12222123,3, '.', '-') // '12-222-123.000'
/*
* 参数说明:
* number:要格式化的数字
* decimals:保留几位小数
* dec_point:小数点符号
* thousands_sep:千分位符号
* */
export function NumberThousand(number, decimals, dec_point, thousands_sep) {
number = (number + "").replace(/[^0-9+-Ee.]/g, "");
let n = !isFinite(+number) ? 0 : +number,
prec = !isFinite(+decimals) ? 2 : Math.abs(decimals),
sep = typeof thousands_sep === "undefined" ? "," : thousands_sep,
dec = typeof dec_point === "undefined" ? "." : dec_point,
s = "",
toFixedFix = function (n, prec) {
var k = Math.pow(10, prec);
return "" + Math.ceil(n * k) / k;
};
s = (prec ? toFixedFix(n, prec) : "" + Math.round(n)).split(".");
let re = /(-?\d+)(\d{3})/;
while (re.test(s[0])) {
s[0] = s[0].replace(re, "$1" + sep + "$2");
}
if ((s[1] || "").length < prec) {
s[1] = s[1] || "";
s[1] += new Array(prec - s[1].length + 1).join("0");
}
return s.join(dec);
}
--------------------------------------------------
comdify('141234124') // '141,234,124.00'
export function comdify( num ) {
if ( num ) {
// 判断是否是纯数字
num = num.toString();
var pattern = /^\d+$/g;
var result = num.match( pattern );
if ( result == null ) {
// 非纯数字
return "0.00";
} else {
// 纯数字
var re = /\d{1,3}(?=(\d{3})+$)/g;
var num1 = num.toString().replace( /^(\d+)((\.\d+)?)$/, function ( s, s1, s2 ) {
return s1.replace( re, "$&," ) + ".00";
} );
return num1;
}
} else {
return "0.00";
}
}
--------------------------------------------------
commafy('10239443223') //'10,239,443,223'
commafy('10239443223',true) // '10,239,443,223.00'
//========处理金钱千分为,小数
export function commafy(num, points) {
if (num) {
//1.先去除空格,判断是否空值和非数
num = num + ''
num = num.replace(/[ ]/g, '') //去除空格
if (num == '') {
return
}
if (isNaN(num)) {
return num
}
//2.针对是否有小数点,分情况处理
var index = num.indexOf('.')
if (index == -1) {
//无小数点
var reg = /(-?\d+)(\d{3})/
while (reg.test(num)) {
num = num.replace(reg, '$1,$2')
}
if(points) {
num += '.00' //强制转为含角分 pcj
}
} else {
var intPart = num.substring(0, index)
var pointPart = num.substring(index + 1, num.length)
//如果输入小数位为1位,追加0
if (pointPart.length == 1) {
pointPart += '0'
}
var reg = /(-?\d+)(\d{3})/
while (reg.test(intPart)) {
intPart = intPart.replace(reg, '$1,$2')
}
num = intPart + '.' + pointPart
}
return num
}
return '0.00'
}
--------------------------------------------------
moneyFormat(10000000) // 10,000,000.00
moneyFormat(10000000, 3, '.', '-') // 10-000-000.000
{number} number:要格式化的数字
{number} decimals:保留几位小数
{string} dec_point:小数点符号
{string} thousands_sep:千分位符号
export const moneyFormat = (number, decimals, dec_point, thousands_sep) => {
number = (number + '').replace(/[^0-9+-Ee.]/g, '')
const n = !isFinite(+number) ? 0 : +number
const prec = !isFinite(+decimals) ? 2 : Math.abs(decimals)
const sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep
const dec = typeof dec_point === 'undefined' ? '.' : dec_point
let s = ''
const toFixedFix = function(n, prec) {
const k = Math.pow(10, prec)
return '' + Math.ceil(n * k) / k
}
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
const re = /(-?\d+)(\d{3})/
while (re.test(s[0])) {
s[0] = s[0].replace(re, '$1' + sep + '$2')
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || ''
s[1] += new Array(prec - s[1].length + 1).join('0')
}
return s.join(dec)
}
67. 存储操作,localStorage优化对应方法存取本地缓存数据 (StorageSetItem / StorageGetItem / StorageRemoveItem ),推荐第二种class的方式
// 第一种:
/**
* 存储数据
*/
export const setItem = ( key, value ) => {
// 将数组、对象类型的数据转换为 JSON 格式字符串进行存储
if ( typeof value === 'object' ) {
value = JSON.stringify( value )
}
window.localStorage.setItem( key, value )
}
/**
* 获取数据
*/
export const getItem = key => {
const data = window.localStorage.getItem( key )
try {
if ( !data ) {
return ""
}
return JSON.parse( data )
} catch ( err ) {
return data
}
}
/**
* 删除数据
*/
export const removeItem = key => {
window.localStorage.removeItem( key )
}
-----------------------------------------------
// 第二种:推荐使用
class类方式优化储存方式:
class MyCache {
constructor(isLocal = true) {
this.storage = isLocal ? localStorage : sessionStorage
}
setItem(key, value) {
if (typeof (value) === 'object') value = JSON.stringify(value)
this.storage.setItem(key, value)
}
getItem(key) {
try {
return JSON.parse(this.storage.getItem(key))
} catch (err) {
return this.storage.getItem(key)
}
}
removeItem(key) {
this.storage.removeItem(key)
}
clear() {
this.storage.clear()
}
key(index) {
return this.storage.key(index)
}
length() {
return this.storage.length
}
}
const localCache = new MyCache()
const sessionCache = new MyCache(false)
export { localCache, sessionCache }
68. base64文件的剪切和拼接转换 (toggleBase64)
/**
*
* @param {String} imgBase64
* @description 切换base64前缀的方法,有则删除无则添加
*/
export function toggleBase64(imgBase64) {
if (!imgBase64) return imgBase64;
let isheader = imgBase64.includes("data:image/png;base64");
return isheader ?
imgBase64.replace("data:image/png;base64,", "") :
`data:image/png;base64,${imgBase64}`;
}
69. 处理提交时间(刚刚、几分钟前、几小时前······)(DateShowTimeStr)
showTime('2022-02-25 10:20:20') // '3小时前'
//展示时间
export function showTime(dateStr) {
if (dateStr) {
dateStr = dateStr.replace(/-/g, "/"); //一般得到的时间的格式都是:yyyy-MM-dd hh24:mi:ss,所以我就用了这个做例子,是/的格式,就不用replace了。
var end_date = new Date(dateStr); //将字符串转化为时间
//开始时间
var curr_date = new Date();
var num = (curr_date - end_date) / (1000 * 3600 * 24); //求出两个时间的天数时间差
var days = parseInt(Math.ceil(num)) - 1; //转化为整天
switch (days) { //天数
case 0: //今天
return currentDayShowTime(curr_date, end_date);
case 1: //昨天
return '昨天';
case 2: //2天前
return '2天前';
case 3: //3天前
return '3天前';
case 4: //4天前
return '4天前';
case 5: //5天前
return '5天前';
case 6: //6天前
return '6天前';
default:
return end_date.getFullYear() + '年' + (end_date.getMonth() + 1) + '月' + end_date.getDate() + '日';
}
}
}
function currentDayShowTime(curr_date, end_date) {
const num = (curr_date - end_date) / (1000 * 3600); //求出两个时间的小时差
const hours = parseInt(Math.ceil(num)) - 1; //转化为整小时
if (hours >= 1) {
return hours + '小时前';
} else {
const num = (curr_date - end_date) / (1000 * 60); //求出两个时间的分钟
const m = parseInt(Math.ceil(num)) - 1; //转化为分钟数
if (m >= 1) {
return m + '分钟前';
} else {
return '刚刚';
}
}
}
70. 金额展示处理,以万为单位展示数值
showMoneyWanUnit(125444) //'12万' 直接舍去万后面的数值
showMoneyWanUnit(125444, true) //'13万' // 万后面的数值千位大于等于5时进1操作
**金额展示,以万为单位 */
export function showMoneyWanUnit( money, flag ) {
if ( !money ) {
return "";
}
let moneyFloat = parseFloat( money );
moneyFloat = Math.round( moneyFloat * 100 ) / 100;
let moneyStr = moneyFloat.toString()
let moneyArray = moneyStr.split( "." );
let moneyReal = moneyArray[ 0 ];
if ( moneyFloat >= 10000.0 ) {
//大于一万
let isFive = moneyStr.slice(-4,-3) > 4 && flag ? 1: 0
moneyReal = moneyReal.slice( 0, moneyReal.length - 4 )
moneyReal = parseFloat(moneyReal ) + isFive
return moneyReal + "万";
} else {
return moneyReal;
}
}
71. 字符串去除所有空格(StringRemoveTrim)
removeTrim("123123 1231244 1242144 124 ")
'12312312312441242144124'
export function removeTrim(str) {
// 去除字符串内所有的空格: str = str.replace(/\s*/g, ""); 去除字符串内两头的空格: str = str.replace(/^\s*|\s*$/g, "");
if (str && typeof str === "string") {
return str.replace(/\s*/g, "")
} else {
return ""
}
}
72. 数组字符串去除多余空格(ArrayRemoveTrim)
substringAddressArr(['12312 3123 ', '1231 - 2 - dadfa '])
(2) ['123123123', '1231-2-dadfa']
/****
* @params Array
* @description 数组字符串去除多余空格
* ****/
export function ArrayRemoveTrim(addressArray) {
// 去除字符串内所有的空格: str = str.replace(/\s*/g, ""); 去除字符串内两头的空格: str = str.replace(/^\s*|\s*$/g, "");
this.removeTrim = (params) => params.replace(/\s*/g, "") // 去除所有空格
let newArray = []
if (addressArray && addressArray instanceof Array) {
addressArray.forEach(value => {
value = this.removeTrim(value)
newArray.push(value)
})
return newArray
} else {
return ""
}
}
73. 校验数据类型, 类型判断,兼容所用类型(替代 typeof / instanceof)(StringTypeOf)
//1. 返回对应的类型
export function returnType(params) {
let type = Object.prototype.toString.call(params)
// '[object Undefined]'
let realType = type.split(" ")[1].substring(0, type.split(" ")[1].length - 1)
return realType
}
//2. 最简洁的检测类型方式:
export const typeOf = function(obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
}
returnType(123124) //'Number'
returnType("4124") // 'String'
typeOf('树哥') // string
typeOf([]) // array
typeOf(new Date()) // date
typeOf(null) // null
typeOf(true) // boolean
typeOf(() => { }) // function
74. 时间处理输入毫秒数或日期格式返回对应的时间(hh:mm:ss)(timeFromDate)
const timeFromDate = date => date.toTimeString().slice(0, 8);
console.log(timeFromDate(new Date(2021, 0, 10, 17, 30, 0)));
// Result: "17:30:00"
timeFromDate(new Date())
// '13:34:05'
75. 检验数字是奇数还是偶数(isEven)
const isEven = num => num % 2 === 0;
console.log(isEven(2));
// Result: True
76. 切换全屏
开启全屏:
export const launchFullscreen = (element) => {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullScreen()
}
}
关闭全屏:
export const exitFullscreen = () => {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
}
}
77. 字符串大小写转换
// type 1-全大写 2-全小写 3-首字母大写
export const turnCase = (str, type = 1) => {
switch (type) {
case 1:
return str.toUpperCase()
case 2:
return str.toLowerCase()
case 3:
//return str[0].toUpperCase() + str.substr(1).toLowerCase() // substr 已不推荐使用
return str[0].toUpperCase() + str.substring(1).toLowerCase()
default:
return str
}
}
78.判断手机是Andoird还是IOS
/**
* 1: ios
* 2: android
* 3: 其它
*/
export const getOSType=() => {
let u = navigator.userAgent, app = navigator.appVersion;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
if (isIOS) {
return 'ios';
}
if (isAndroid) {
return 'adnroid';
}
return '其他';
}
79.数组对象根据字段去重
arr 要去重的数组
key 根据去重的字段名
export const uniqueArrayObject = (arr = [], key = 'id') => {
if (arr.length === 0) return
let list = []
const map = {}
arr.forEach((item) => {
if (!map[item[key]]) {
map[item[key]] = item
}
})
list = Object.values(map)
return list
}
80.滚动到页面顶部
export const scrollToTop = () => {
const height = document.documentElement.scrollTop || document.body.scrollTop;
if (height > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, height - height / 8);
}
}
81.滚动到元素位置
// 入参:类名或者id名或者标签(原生的获取,非jquery)
moothScroll('#target'); // 平滑滚动到 ID 为 target 的元素
export const smoothScroll = element =>{
document.querySelector(element).scrollIntoView({
behavior: 'smooth'
});
};
82.前端生成uuid
// '325fe879-cabd-4870-b105-ccdeacf2efba'
export const uuid = () => {
const temp_url = URL.createObjectURL(new Blob())
const uuid = temp_url.toString()
URL.revokeObjectURL(temp_url) //释放这个url
return uuid.substring(uuid.lastIndexOf('/') + 1)
}
83.下载文件
api 接口
params 请求参数
fileName 文件名
const downloadFile = (api, params, fileName, type = 'get') => {
axios({
method: type,
url: api,
responseType: 'blob',
params: params
}).then((res) => {
let str = res.headers['content-disposition']
if (!res || !str) {
return
}
let suffix = ''
// 截取文件名和文件类型
if (str.lastIndexOf('.')) {
fileName ? '' : fileName = decodeURI(str.substring(str.indexOf('=') + 1, str.lastIndexOf('.')))
suffix = str.substring(str.lastIndexOf('.'), str.length)
}
// 如果支持微软的文件下载方式(ie10+浏览器)
if (window.navigator.msSaveBlob) {
try {
const blobObject = new Blob([res.data]);
window.navigator.msSaveBlob(blobObject, fileName + suffix);
} catch (e) {
console.log(e);
}
} else {
// 其他浏览器
let url = window.URL.createObjectURL(res.data)
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName + suffix)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(link.href);
}
}).catch((err) => {
console.log(err.message);
})
}
84.模糊搜索
// 方法:
参数:
list 原数组
keyWord 查询的关键词
attribute 数组需要检索属性
export const fuzzyQuery = (list, keyWord, attribute = 'name') => {
const reg = new RegExp(keyWord)
const arr = []
for (let i = 0; i < list.length; i++) {
if (reg.test(list[i][attribute])) {
arr.push(list[i])
}
}
return arr
}
// 示例:
const list = [
{ id: 1, name: '树哥' },
{ id: 2, name: '黄老爷' },
{ id: 3, name: '张麻子' },
{ id: 4, name: '汤师爷' },
{ id: 5, name: '胡万' },
{ id: 6, name: '花姐' },
{ id: 7, name: '小梅' }
]
fuzzyQuery(list, '树', 'name') // [{id: 1, name: '树哥'}]
85.遍历树节点
// 函数:
export const foreachTree = (data, callback, childrenName = 'children') => {
for (let i = 0; i < data.length; i++) {
callback(data[i])
if (data[i][childrenName] && data[i][childrenName].length > 0) {
foreachTree(data[i][childrenName], callback, childrenName)
}
}
}
// 示例:
const treeData=[{id:1,label:'一级 1',children:[{id:4,label:'二级 1-1',children:[{id:9,label:'三级 1-1-1'},{id:10,label:'三级 1-1-2'}]}]},{id:2,label:'一级 2',children:[{id:5,label:'二级 2-1'},{id:6,label:'二级 2-2'}]},{id:3,label:'一级 3',children:[{id:7,label:'二级 3-1'},{id:8,label:'二级 3-2'}]}]
let result = {}
foreachTree(data, (item) => {
if (item.id === 9) {
result = item
}
})
console.log('result', result) // {id: 9,label: "三级 1-1-1"}