这些JS工具函数够你用到2020年底了

Jacquelyn38
• 阅读 1327

前言

活不多说,自己平时搜集的干货函数奉上。

干货函数

找出数字在数组中下一个相邻的元素

let i = "";  
let rr = [];  

const name = (n, arr1)=>{  
    let num = Number(n);  
    for (let i = 0; i < arr1.length; i++) {  
        const element = arr1[i];  
        if (element != num) {  
            rr.push(num--);  
        }  
    }  
    return rr.find((el) => {  
        let newel = String(el);  
        return arr1.includes(newel);  
    })}  

let arr = ["2", "4", "6", "8", "10", "12", "14", "16", "18", "20", "22", "24", "27", "30", "33", "36", "42", "48", "54", "60"]  
console.log(name('5',arr)); //4  

格式化时间

/**  
 * @param {number} time  
 * @param {string} option  
 * @returns {string}  
 */  
function formatTime(time, option) {  
  if (('' + time).length === 10) {  
    time = parseInt(time) * 1000  
  } else {  
    time = +time  
  }  
  const d = new Date(time)  
  const now = Date.now()  

  const diff = (now - d) / 1000  

  if (diff < 30) {  
    return '刚刚'  
  } else if (diff < 3600) {  
    // less 1 hour  
    return Math.ceil(diff / 60) + '分钟前'  
  } else if (diff < 3600 * 24) {  
    return Math.ceil(diff / 3600) + '小时前'  
  } else if (diff < 3600 * 24 * 2) {  
    return '1天前'  
  }  
  if (option) {  
    return parseTime(time, option)  
  } else {  
    return (  
      d.getMonth() +  
      1 +  
      '月' +  
      d.getDate() +  
      '日' +  
      d.getHours() +  
      '时' +  
      d.getMinutes() +  
      '分'  
    )  
  }  
}  

解析时间

/**  
 * Parse the time to string  
 * @param {(Object|string|number)} time  
 * @param {string} cFormat  
 * @returns {string | null}  
 */  
function parseTime(time, cFormat) {  
  if (arguments.length === 0 || !time) {  
    return null  
  }  
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'  
  let date  
  if (typeof time === 'object') {  
    date = time  
  } else {  
    if ((typeof time === 'string')) {  
      if ((/^[0-9]+$/.test(time))) {  
        // support "1548221490638"  
        time = parseInt(time)  
      } else {  
        // support safari  
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari  
        time = time.replace(new RegExp(/-/gm), '/')  
      }  
    }  

    if ((typeof time === 'number') && (time.toString().length === 10)) {  
      time = time * 1000  
    }  
    date = new Date(time)  
  }  
  const formatObj = {  
    y: date.getFullYear(),  
    m: date.getMonth() + 1,  
    d: date.getDate(),  
    h: date.getHours(),  
    i: date.getMinutes(),  
    s: date.getSeconds(),  
    a: date.getDay()  
  }  
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {  
    const value = formatObj[key]  
    // Note: getDay() returns 0 on Sunday  
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }  
    return value.toString().padStart(2, '0')  
  })  
  return time_str  
}  

解析Url地址

/**  
 * @param {string} url  
 * @returns {Object}  
 */  
function param2Obj(url) {  
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')  
  if (!search) {  
    return {}  
  }  
  const obj = {}  
  const searchArr = search.split('&')  
  searchArr.forEach(v => {  
    const index = v.indexOf('=')  
    if (index !== -1) {  
      const name = v.substring(0, index)  
      const val = v.substring(index + 1, v.length)  
      obj[name] = val  
    }  
  })  
  return obj  
}  

合并两个对象

/**  
 * Merges two objects, giving the last one precedence  
 * @param {Object} target  
 * @param {(Object|Array)} source  
 * @returns {Object}  
 */  
function objectMerge(target, source) {  
  if (typeof target !== 'object') {  
    target = {}  
  }  
  if (Array.isArray(source)) {  
    return source.slice()  
  }  
  Object.keys(source).forEach(property => {  
    const sourceProperty = source[property]  
    if (typeof sourceProperty === 'object') {  
      target[property] = objectMerge(target[property], sourceProperty)  
    } else {  
      target[property] = sourceProperty  
    }  
  })  
  return target  
}  

数组去重

/**  
 * @param {Array} arr  
 * @returns {Array}  
 */  
function uniqueArr(arr) {  
  return Array.from(new Set(arr))  
}  

防抖

/**  
 * @param {Function} func  
 * @param {number} wait  
 * @param {boolean} immediate  
 * @return {*}  
 */  
function debounce(func, wait, immediate) {  
  let timeout, args, context, timestamp, result  

  const later = function() {  
    // 据上一次触发时间间隔  
    const last = +new Date() - timestamp  

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait  
    if (last < wait && last > 0) {  
      timeout = setTimeout(later, wait - last)  
    } else {  
      timeout = null  
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用  
      if (!immediate) {  
        result = func.apply(context, args)  
        if (!timeout) context = args = null  
      }  
    }  
  }  

  return function(...args) {  
    context = this  
    timestamp = +new Date()  
    const callNow = immediate && !timeout  
    // 如果延时不存在,重新设定延时  
    if (!timeout) timeout = setTimeout(later, wait)  
    if (callNow) {  
      result = func.apply(context, args)  
      context = args = null  
    }  

    return result  
  }  
}  

简易搜索

<!DOCTYPE html>  
<html lang="en">  
<head>  
  <meta charset="UTF-8">  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  <title>Document</title>  
</head>  
<body>  
  <input type="text" id="int">  
</body>  
<script> let list = ["示例1","示例12","示例5","示例56"];  
  document.querySelector('#int').onchange=function(e){  
    console.log(search(e.target.value));  
  }  

  function search(val) {  
    if (val) {  
        return list.filter(function (item) {  
          return Object.keys(item).some(function (key) {  
            return String(item[key]).toLowerCase().indexOf(val) > -1  
          })  
        })  
    }  
    return list   
  }</script>  
</html>  

将秒化为时分秒

function formateSeconds (endTime) {  
      let secondTime = parseInt(endTime); //将传入的秒的值转化为Number  
      let min = 0; // 初始化分  
      let h = 0; // 初始化小时  
      let result = "";  
      if (secondTime > 60) {  
        //如果秒数大于60,将秒数转换成整数  
        min = parseInt(secondTime / 60); //获取分钟,除以60取整数,得到整数分钟  
        secondTime = parseInt(secondTime % 60); //获取秒数,秒数取佘,得到整数秒数  
        if (min > 60) {  
          //如果分钟大于60,将分钟转换成小时  
          h = parseInt(min / 60); //获取小时,获取分钟除以60,得到整数小时  
          min = parseInt(min % 60); //获取小时后取佘的分,获取分钟除以60取佘的分  
        }  
      }  
      result = `${h.toString().padStart(2, "0")}:${min.toString().padStart(2, "0")}:${secondTime.toString().padStart(2, "0")}`;  
      return result;  
    }

将时分秒化为秒

function formSeconds (times) {  
        let arr = times.split(":");  
        let s = arr[2];  
        let m = arr[1];  
        let h = arr[0];  
        let m1 = m<10?m.replace(/\b(0+)/gi,""):m;  
        let h1 = h<10?h.replace(/\b(0+)/gi,""):h;  
        return m1*60+Number(h1)+Number(s)  
}  

对象深层遍历

var obj = {  
  a:{  
   b:{  
    c:"maomin"  
   }  
  }  
 }  
const safeGet = (obj, path) => {  
        try {  
          return path.split('.').reduce((o, k) => o[k], obj)  
        } catch (e) {  
          return undefined  
        }  
    }  
console.log(safeGet(obj,'a.b.c'));// maomin  

带有分割符的字符串转化成一个n维数组

 var str = "A-2-12";  
 var str1 = str.split('-');  
 var arr = str1.reverse().reduce((pre,cur,i) => {  
 if(i==0)  
  { pre.push(cur)  
   return pre  
 }  
  return [cur,pre]  
},[])  
console.log(arr) // ["A"["B",["C"]]]

获取时间戳

 function thedata(d){  
      return d.replace(/\-/g, "\/")  
  }  
  var serverTime = parseInt(new Date(thedata('2020-08-12 15:52:11')).valueOf());  
  console.log(serverTime); // 1597218731000,获取到时间戳

对象深拷贝

function deepClone(target) {  
    // 定义一个变量  
    let result;  
    // 如果当前需要深拷贝的是一个对象的话  
    if (typeof target === 'object') {  
    // 如果是一个数组的话  
        if (Array.isArray(target)) {  
            result = []; // 将result赋值为一个数组,并且执行遍历  
            for (let i in target) {  
                // 递归克隆数组中的每一项  
                result.push(deepClone(target[i]))  
            }  
         // 判断如果当前的值是null的话;直接赋值为null  
        } else if(target===null) {  
            result = null;  
         // 判断如果当前的值是一个RegExp对象的话,直接赋值   
        } else if(target.constructor===RegExp){  
            result = target;  
        }else {  
         // 否则是普通对象,直接for in循环,递归赋值对象的所有值  
            result = {};  
            for (let i in target) {  
                result[i] = deepClone(target[i]);  
            }  
        }  
     // 如果不是对象的话,就是基本数据类型,那么直接赋值  
    } else {  
        result = target;  
    }  
     // 返回最终结果  
    return result;  
}  

简易版对象拷贝

 function copy(obj) {  
    if(typeof obj == "object") { //判断是否复杂类型  
       var result = obj.constructor == Array ? [] : {};//判断数组类型或是object,数组即result=[],object即result={}  
        for(let i in obj) {  
            result[i] = typeof obj[i] == "object" ? copy(obj[i]) : obj[i]//判断数据每一项是否是object  
        }  
    } else {  
        var result = obj //基本类型直接拷贝  
    }  
  return result;  
}

实现一个模板引擎

function render(template, data) {  
  const reg = /\{\{(\w+)\}\}/; // 模板字符串正则  
  if (reg.test(template)) { // 判断模板里是否有模板字符串  
    const name = reg.exec(template)[1]; // 查找当前模板里第一个模板字符串的字段  
    template = template.replace(reg, data[name]); // 将第一个模板字符串渲染  
    return render(template, data); // 递归的渲染并返回渲染后的结构  
  }  
  return template; // 如果模板没有模板字符串直接返回  
}  
let template = '我是{{name}},年龄{{age}},性别{{sex}}';  
let data = {  
  name: '姓名',  
  age: 18  
}  
render(template, data); // 我是姓名,年龄18,性别undefined  

节流

// ①定时器实现  
const throttle = (fn,delay = 500) =>{  
  let flag = true;  
  return (...args) => {  
    if(!flag) return;  
    flag = false;  
    setTimeout(() => {  
      fn.apply(this,args);  
      flag = true;  
    },delay);  
  };  
}  
// ②时间戳实现  
const throttle = (fn,delay = 500) => {  
  let preTime = Date.now();  
  return (...args) => {  
    const nowTime = Date.now();  
    if(nowTime - preTime >= delay){  
       preTime = Date.now();  
       fn.apply(this,args);  
    }  
  }  
}  

封装fetch

/**  
 * 封装fetch函数,用Promise做回调  
 * @type {{get: (function(*=)), post: (function(*=, *=))}}  
 */  
const fetchUtil = {  
    get: (url) => {  
        return new Promise((resolve, reject) => {  
            fetch(url, {  
                method: 'GET',  
                headers: {  
                    'Content-Type': 'application/x-www-form-urlencoded',  
                }  
            }).then((response) => response.json()).then(response => {  
                resolve(response);  
            }).catch(err => {  
                reject(new Error(err));  
            });  
        });  
    },  
    post: (url, params) => {  
        return new Promise((resolve, reject) => {  
            fetch(url, {  
                method: 'POST',  
                headers: {  
                    'Content-Type': 'application/x-www-form-urlencoded',  
                },  
                body: params  
            }).then((response) => response.json()).then(response => {  
                resolve(response);  
            }).catch(err => {  
                reject(new Error(err));  
            });  
        });  
    }  
};  

判断浏览器环境

function getSystem(){  
    const mac = /mac/i,  
        linux = /linux/i,  
        win = /win/i;  
    const platform = navigator.platform.toLowerCase();  
    if(mac.test(platform)){  
        return 'MAC';  
    } else if(win.test(platform)){  
        return 'WIN';  
    } else if(linux.test(platform)){  
        return 'Linux';  
    }  
    return undefined;  
}  
const browser = {   
    versions:function(){   
        let ret = 'xxSys';  
        const u = navigator.userAgent;  
        const isMobile = !!u.match(/AppleWebKit.*Mobile.*/),  
            ios = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),  
            android = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;  
        if(isMobile){  
            if(ios) return 'IOS';  
            if(android) return 'Android';  
        } else {  
            ret = getSystem() || ret;  
        }  
        return ret;  
    }(),  
};  

定义数组内部对象形式

const objArrtransArr = (olddata, oldval, oldname)=>{  
    const newArr = [];  
    olddata.forEach(item => {  
        // 定义数组内部对象形式  
        let obj = {};  
        obj.value = item[oldval];  
        obj.name = item[oldname];  
        // 将对象数据推到数组中  
        newArr.push(obj);  
    });  
    return newArr;  
}  

解析html字符串

function (htmlobj) {  
       var el = document.createElement('div');  
       el.innerHTML = htmlobj;  
       var tags = el.getElementsByTagName('img');  
       var text = tags[0].getAttribute("src");  
       return text;  
}  

判断浏览器是否支持摄像头

function videoCheck () {  
      var deviceList = [];  
      navigator.mediaDevices  
        .enumerateDevices()  
        .then(devices => {  
          devices.forEach(device => {  
            deviceList.push(device.kind);  
          });  
          if (deviceList.indexOf("videoinput") == "-1") {  
            console.info("没有摄像头");  
            return false;  
          } else {  
            console.info("有摄像头");  
          }  
        })  
        .catch(function(err) {  
          alert(err.name + ": " + err.message);  
        });  
    }  

回文算法

 //忽略标点符号、大小写和空格,正着读和反着读一模一样。  
function made(str) {  
        var str1 = str.toLowerCase(); //先将字符串全部转换为小写  
        var reg = /[\W\_]/g; // 删除所有非字母数字字符和下划线  
        var str2 = str1.replace(reg, ""); // 去掉非字母和非数字  
        var str3 = str2.split(""); // 字符串分隔成数组  
        var str4 = str3.reverse(); // 反转数组中的元素  
        var str5 = str4.join(""); // 反转后的数组转化为字符串  
        return str2 === str5;  
}

持续更新...

结语

  • 欢迎关注我的公众号前端历劫之路

  • 回复关键词电子书,即可获取12本前端热门电子书。

  • 回复关键词红宝书第4版,即可获取最新《JavaScript高级程序设计》(第四版)电子书。

  • 关注公众号后,点击下方菜单即可加我微信,我拉拢了很多IT大佬,创建了一个技术交流、文章分享群,期待你的加入。这些JS工具函数够你用到2020年底了

- END -

这些JS工具函数够你用到2020年底了

本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/R2q8swcbdF5uVAKWS-5Gyw,如有侵权,请联系删除。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Wesley13 Wesley13
2年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
2年前
ES6 简单整理
1.变量声明let和constlet与const都是块级作用域,letfunctionname(){letage12;//age只在name()函数中存在}constconstname'tom'name'jack'//
Stella981 Stella981
2年前
LeetCode 5561. 获取生成数组中的最大值
文章目录1\.题目2\.解题1\.题目给你一个整数n。按下述规则生成一个长度为n1的数组nums:nums00nums11当2<2i<n时,nums2inumsi
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_