Skip to content

整理收集的JavaScript工具类与方法合集,其实有不少工具类开源项目已经实现了不少,开箱即用。常见工具类如下:

  • 工具类

    • Ramda Ramda 是一个功能丰富的 JavaScript 函数式编程库,它提供了一套强大的函数工具,用于处理和操作数据。与 Lodash 不同,Ramda 是专注于函数式编程范式的库。
    • Lodash Lodash是一个JavaScript实用库,提供了对数组、对象、字符串等的有用函数。目前因为方法老旧及冗余,已经被诟病很久,并且出现众多挑战者,例如下面Radash。
    • Radash radash是一个强大的零依赖的前端工具库。如果你会使用lodash,那么你使用radash将没有任何门槛,比lodash更轻量、全面且易于理解的前端工具库。
  • 时间相关库

    • Day.js Day.js 是一个轻量级的 JavaScript 日期和时间处理库,它提供了简洁易用的 API,用于解析、操作和格式化日期和时间。
  • 地理信息

    • Turf.js Turf 是一个用于地理空间分析和操作的 JavaScript 库。它提供了许多方便的函数和工具,用于处理地理数据、执行地理空间计算和分析以及创建交互式地图应用程序。
  • 展示相关

    • cleave-zen 数字格式化,比如信用卡,时间,电话号码等等
    • reveal.js HTML演示文稿框架。

防抖debounce

代码

javascript
function debounce(func, wait, immediate) {

    var timeout, result;

    var debounced = function () {
        var context = this;
        var args = arguments;

        if (timeout) clearTimeout(timeout);
        if (immediate) {
            // 如果已经执行过,不再执行
            var callNow = !timeout;
            timeout = setTimeout(function(){
                timeout = null;
            }, wait)
            if (callNow) result = func.apply(context, args)
        }
        else {
            timeout = setTimeout(function(){
                func.apply(context, args)
            }, wait);
        }
        return result;
    };

    debounced.cancel = function() {
        clearTimeout(timeout);
        timeout = null;
    };

    return debounced;
}

使用

javascript
function getUserAction(e) {
   ...
};

// 防抖
var setUseAction = debounce(getUserAction, 10000, true);

// 取消
setUseAction.cancel();

节流throttle

代码

javascript
function throttle(func, wait, options) {
    var timeout, context, args, result;
    var previous = 0;
    if (!options) options = {};

    var later = function() {
        previous = options.leading === false ? 0 : new Date().getTime();
        timeout = null;
        func.apply(context, args);
        if (!timeout) context = args = null;
    };

    var throttled = function() {
        var now = new Date().getTime();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
    };

    throttled.cancel = function() {
        clearTimeout(timeout);
        previous = 0;
        timeout = null;
    };

动态加载第三方JS

代码

javascript
function loadScript(src, callback) {
  var script = document.createElement('script'),
    head = document.getElementsByTagName('head')[0];
  script.type = 'text/javascript';
  script.charset = 'UTF-8';
  script.src = src;
  if (script.addEventListener) {
    script.addEventListener('load', function () {
      callback();
    }, false);
  } else if (script.attachEvent) {
    script.attachEvent('onreadystatechange', function () {
      var target = window.event.srcElement;
      if (target.readyState == 'loaded') {
        callback();
      }
    });
  }
  head.appendChild(script);
}

使用

javascript
loadScript('https://cdn.bootcss.com/Turf.js/5.1.6/turf.min.js',function(){
  console.log('onload');
  console.log(turf);
});

获取当前JS路径

js
function getPath() {
    let jsPath = document.currentScript ? document.currentScript.src : function () {
        let js = document.scripts
            , last = js.length - 1
            , src;
        for (let i = last; i > 0; i--) {
            if (js[i].readyState === 'interactive') {
                src = js[i].src;
                break;
            }
        }
        return src || js[last].src;
    }();
    return jsPath.substring(0, jsPath.lastIndexOf('/') + 1);
}

alert(getPath());

随机整数

js
var min = 5;
var max = 10;
var rand = Math.floor(Math.random()*(max-min+1))+min;

时间格式化

js
Date.prototype.Format = function(fmt) { //author: meizz
	var o = {
		"M+": this.getMonth() + 1, //月份
		"d+": this.getDate(), //日
		"h+": this.getHours(), //小时
		"m+": this.getMinutes(), //分
		"s+": this.getSeconds(), //秒
		"q+": Math.floor((this.getMonth() + 3) / 3), //季度
		"S": this.getMilliseconds() //毫秒
	};
	if (/(y+)/.test(fmt))
		fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
	for (var k in o)
		if (new RegExp("(" + k + ")").test(fmt))
			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
	return fmt;
}

JSON结构数据转树结构

代码

javascript
function transData(a, idStr, pidStr, chindrenStr) {
    var r = [], hash = {}, id = idStr, pid = pidStr, children = chindrenStr, i = 0, j = 0, len = a.length;
    for (; i < len; i++) {
        hash[a[i][id]] = a[i];
    }
    for (; j < len; j++) {
        var aVal = a[j], hashVP = hash[aVal[pid]];
        if (hashVP) {
            !hashVP[children] && (hashVP[children] = []);
            hashVP[children].push(aVal);
        } else {
            r.push(aVal);
        }
    }
    return r;
}

使用

javascript
function test() {
    //json串
    var jsonData = eval('[{"belongsname":"","id":901,"isleaf":0,"name":"XJBHX-2标项目部","pid":"","type":""},{"belongsname":"","id":902,"isleaf":1,"name":"综合部(办公室)","pid":"901","type":""},{"belongsname":"","id":903,"isleaf":1,"name":"工程部(工技部/技术部)","pid":"901","type":""},{"belongsname":"","id":904,"isleaf":1,"name":"安质部","pid":"901","type":""},{"belongsname":"","id":905,"isleaf":1,"name":"计财部","pid":"901","type":""},{"belongsname":"","id":906,"isleaf":1,"name":"物设部(物机部)","pid":"901","type":""},{"belongsname":"","id":907,"isleaf":1,"name":"中心试验室","pid":"901","type":""}]');
    //绑定的字段
    var jsonDataTree = transData(jsonData, 'id', 'pid', 'chindren');
    console.log(jsonDataTree);
}

千分位

方法一:倒序遍历

js
function qianfenwei(num) {
  // 0. 将数字转成字符
  num += '';
  let result = '';
  // 1.倒序遍历
  num = num.split('').reverse();
  num.forEach((v, i) => {
    // 2.遍历时,后遍历的数需放入先遍历的数前面
    result = v + result;
    // 3.每隔3位加一个逗号
    if (i % 3 === 2 && i !== num.length - 1) {
      result = ',' + result;
    }
  });
  console.log(result);
  return result;
}

方法二:分开处理

js
// 将数字分为长度是3倍数的部分和剩余部分 
function qianfenwei2(num) {
   const len = num.length;
   // 获取剩余长度
   const remainderLen = len % 3;
   // 取出剩余字符串
   const result = remainderLen ? [num.substring(0, remainderLen)] : [];
   // 对其余长度是3的倍数的字符做遍历
   for (let i = remainderLen; i < len; i += 3) {
     result.push(num.substring(i, i + 3));
   }
   console.log(result.join(','));
   return result.join(',');
 }

方法三:正则表达式

js
function qianfenwei3(num) {
  // 正则1:
  // const len = num.length;
  // 将字符填充为长度是3倍速的字符,在数字最前面填充0
  // const splitCount = Math.ceil(len / 3);
  // num = num.padStart(splitCount * 3, '0');
  // 每遇到三个数字就多加一个逗号
  // let result = num.replace(/(\d{3})/g,'$1,');
  // 将结果最前面的0及最末尾的逗号都替换为空
  // result = result.replace(/^0/g, '').replace(/,$/,'');

  // 正则2:
  // 替换后面是一个或多个3个数字且不是开头位置的地方为,
  const result = num.replace(/(?<!^)(?=(\d{3})+$)/g, ',');
  console.log(result);
  return result;
}

localStorage同页面监听

js
var oriSetItem = localStorage.setItem;
localStorage.setItem = function (key, value) {
    //这里抛出自定义事件
    var event = new Event("setItemEvent");
    event.newValue = value;
    window.dispatchEvent(event);

    //实现原方法
    oriSetItem.apply(this, arguments);
}

然后就能在当前页监听 setItemEvent 啦。window.addEventListener("setItemEvent", function (e) {
    console.log("本地存储已变化,新值为" + e.newValue);
});

深copy

javascript
function deepCopy(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    if (Array.isArray(obj)) {
        const arrCopy = [];
        for (let i = 0; i < obj.length; i++) {
            arrCopy[i] = deepCopy(obj[i]);
        }
        return arrCopy;
    }

    const objCopy = {};
    for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
            objCopy[key] = deepCopy(obj[key]);
        }
    }
    return objCopy;
}

// 示例

js
const original = {
    a: 1,
    b: {
        c: 2,
        d: [3, 4]
    }
};

const copied = deepCopy(original);
console.log(copied);
console.log(original === copied); // false
console.log(original.b === copied.b); // false