JavaScript------常用JS方法(utils.js)骨灰级总结

  

 已上传到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"}   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绝世唐门三哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值