tool

300 阅读2分钟

这里存放常用的工具函数

1.节流函数

/** 函数节流
 * @param { function } fn 要节流的函数
 * @param { number } interval 时间间隔,每个时间间隔内至多执行一次, 并使用最后一次调用时传入的参数
 * @returns { function } 节流函数
 */
export const throttle = function (fn, interval = 1000 / 30) {
  let timer = null
  let params = null
  return function (...args) {
    params = args
    if (timer) {
      return
    }
    timer = setTimeout(() => {
      fn.apply(this, params)
      timer = null
    }, interval)
  }
}

2.全局绑定键盘事件

/**
 * 全局键盘事件绑定
 * @params {eventName: 事件名, key: 按下的按键, callback:回调}
 * @returns { functions } 
 */
export function keyboardEvent({ eventName, key, callback }) {
  const handler = function (event) {
    if (key) {
      if (key === event.key) {
        callback(event);
      }
    } else {
      callback(event);
    }
  };
  window.addEventListener(eventName, handler);
  return function () {
    window.removeEventListener(eventName, handler);
  };
}
// 调用
keyboardEvent({
  eventName: 'keydown',
  key: 'Escape',
  callback: () => {
    this.$emit('close');
  },
});

3.获取cookie

/**
 * @description 通过名称查询cookie信息
 * @parmas {name} cookie名称
 * @return {String} cookie值
*/
const getCookieByName = (name) => {
  let prefix = name + "="
  let start = document.cookie.indexOf(prefix)
  if (start === -1) return null;

  let end = document.cookie.indexOf(";", start + prefix.length)
  if (end === -1) {
      end = document.cookie.length;
  }

  let value = document.cookie.substring(start + prefix.length, end)
  return unescape(value);
}

4.判断是否为空对象的几种方法

function isEmptyObject(object) {
  return JSON.stringify(object) === "{}";
}

function isEmptyObject2(object) {
  for (const key in object) {
    return false;
  }
  return true;
}

function isEmptyObject3(object) {
  return Object.getOwnPropertyNames(object).length === 0;
}

function isEmptyObject4(object) {
  return Object.keys(object).length === 0;
}

5.给元素绑定事件

此方法来源于Element-ui 源码当中

  const on = (function() {
    if (document.addEventListener) {
      return function(element, event, handler) {
        if (element && event && handler) {
          element.addEventListener(event, handler, false)
        }
      }
    } else {
      return function(element, event, handler) {
        if (element && event && handler) {
          element.attachEvent('on' + event, handler)
        }
      }
    }
  })()

  const off = (function() {
    if (document.removeEventListener) {
      return function(element, event, handler) {
        if (element && event) {
          element.removeEventListener(event, handler, false)
        }
      }
    } else {
      return function(element, event, handler) {
        if (element && event) {
          element.detachEvent('on' + event, handler)
        }
      }
    }
  })()
  
  // 用法
  const mousedownHandler = (event) => {
    console.log(event)
  }
  on(document.getElementById('id'), 'mousedown', mousedownHandler)
  off(document.getElementById('id'), 'mousedown', mousedownHandler)

6.使用clipboard

import Clipboard from 'clipboard'
const VueClipboardConfig = {
  autoSetContainer: false,
  appendToBody: true // This fixes IE, see #50
}
function copyText(text, container) {
  return new Promise(function(resolve, reject) {
    var fakeElement = document.createElement('button')
    var clipboard = new Clipboard(fakeElement, {
      text: function() { return text },
      action: function() { return 'copy' },
      container: typeof container === 'object' ? container : document.body
    })
    clipboard.on('success', function(e) {
      clipboard.destroy()
      resolve(e)
    })
    clipboard.on('error', function(e) {
      clipboard.destroy()
      reject(e)
    })
    if (VueClipboardConfig.appendToBody) document.body.appendChild(fakeElement)
    fakeElement.click()
    if (VueClipboardConfig.appendToBody) document.body.removeChild(fakeElement)
  })
}
// 用法
copyText('data').then(res => {
    console.log('复制成功')
}, error => {
    console.log('复制失败’)
})

7.数组分割

function Chunk(arr = [], size = 1) { 
        return arr.length ? arr.reduce((t, v) => (t[t.length - 1].length === size ? t.push([v]) : t[t.length - 1].push(v), t), [[]]) : []; }

// 用法
const arr = [1, 2, 3, 4, 5]; 
Chunk(arr, 2); // [[1, 2], [3, 4], [5]]

8.Url 参数反序列化

function ParseUrlSearch() {
  return location.search
    .replace(/(^\?)|(&$)/g, "")
    .split("&")
    .reduce((t, v) => {
      const [key, val] = v.split("=");
      t[key] = decodeURIComponent(val);
      return t;
    }, {});
}
// 假设URL为:https://www.baidu.com?age=25&name=TYJ
ParseUrlSearch(); // { age: "25", name: "TYJ" }

9.Url参数序列化

function StringifyUrlSearch(search = {}) {
  return Object.entries(search)
    .reduce(
      (t, v) => {
        return `${t}${v[0]}=${encodeURIComponent(v[1])}&`;
      },
      Object.keys(search).length ? "?" : ""
    )
    .replace(/&$/, "");
}

const res = StringifyUrlSearch({ age: 27, name: "YZW" });
console.log(res); // ?age=27&name=YZW

10.字符串指定位置插入内容

function insertStrByIndex(source,index,target) {
    return source.slice(0,index) + target + source.slice(index)
}

11.通过 Blob 下载文件

function downloadByBlob(filename = '文件名', blobData) {
  const blob = new Blob([blobData], { type: "application/json" });
  let dom = document.createElement("a");
  let url = window.URL.createObjectURL(blob);
  dom.href = url;
  dom.download = decodeURI(filename);
  dom.style.display = "none";
  document.body.appendChild(dom);
  dom.click();
  dom.parentNode.removeChild(dom);
  window.URL.revokeObjectURL(url);
}

12.字符串根据最后一次出现的位置分割(split by last)

输入:123.2345.34

输出:['123.2345', '34']

var array = '123.2345.34'.split(/.(?=[^.]+$)/);
console.log(array);

13.颠倒对象的key,value的两种方法

function invert(obj) {
  // 这里, 对象的key 可以使用 [] 来表示
  return Object.keys(obj).reduce((res, key) => Object.assign(res, { [obj[key]]: key}), {})
}

function invert2(obj) {
  return Object.fromEntries(Object.entries(obj).map(([key, value]) => [value, key]))
}

const res1 = invert({ a: '1', b: '2', c: '3' })
const res2 = invert2({ a: '1', b: '2', c: '3' })
console.log(res1);
console.log(res2);

14.根据指定的key 忽略对象的一部分属性

// 根据指定的key 忽略对象的一部分属性
// omit a subset of properties of an object 

function omit(obj, keys) {
  return Object.keys(obj)
    .filter(v => !keys.includes(v))
    .reduce((res, key) => Object.assign(res, { [key]: obj[key] }), {})
}

const res = omit({ name: 'name', age: 12, sex: 'man' }, ['name', 'age'])
console.log(res); // {sex: 'man' }

15.根据指定的key 获取对象的一部分属性

// 根据指定的key, 获取对象的的一部分属性
// pick a subset of properties of an object

function pick(obj, keys) {
  return Object.keys(obj)
    .filter(key => keys.includes(key))
    .reduce((res, key) => Object.assign(res, { [key]: obj[key]}),{})
}

const res = pick({ a: "1", b: "2", c: "3" }, ["a", "b"]);
console.log(res); //  a: '1', b: '2' }

16.去除对象中所有的 null 和 undefined 的几种方法

// 去除对象中所有的 null 和 undefined 的几种方法

function removeNullUndefined(obj) {
  // 这里需要注意的是 null == undefined 结果为 true
  return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null))
}


function removeNullUndefined2(obj) {
  return Object.entries(obj).reduce(
    (res, [key, value]) => (value == null ? res : (res[key] = value), res),
    {}
  );
}

function removeNullUndefined3(obj) {
  return Object.entries(obj)
    .filter((([key, value]) => value != null))
    .reduce((res, [key, value]) => ({ ...res, [key]: value}), {})
}
 
const res1 = removeNullUndefined({
  name: null,
  age: undefined,
  sex: 1
})

const res2 = removeNullUndefined2({
  name: null,
  age: undefined,
  sex: 1,
});

const res3 = removeNullUndefined3({
  name: null,
  age: undefined,
  sex: 1,
});
console.log(res1);
console.log(res2);
console.log(res3)

17 生成一个随机布尔值

// 生成一个随机的 布尔值
// generate a random boolean
function generateRandomBoolean() {
  return Math.random() >= 0.5
}

18 指定范围内生成浮点数

// 在指定范围内生成浮点数
// generate a randowm floating point number in given range 
function generateFloatInRange(min, max) {
  return Math.random() * (max - min) + min
}

const res = generateFloatInRange(10, 100)
console.log(res);

19 生成随机颜色

// 生成随机 16 禁止颜色
// generate randow hex color
function generateRandomHexColor() {
  return `#${Math.random().toString(16).slice(2, 8).padEnd(6, "0")}`;
}
const res = generateRandomHexColor()
console.log(res);

20 指定范围生成一个整数


// 根据指定范围生成一个随机整数
// generate a random integer in given range

const randomInteger = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

21 生成随机字符串

// 根据指定字符,生成指定字符串
// generate a randow string from given characters
function randomString(length, chars) {
  return Array(length)
    .fill("")
    .map((v) => chars[Math.floor(Math.random() * chars.length)])
    .join('')
}

const resStr = randomString(
  10,
  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
console.log(resStr);

22 生成全为整数的随机数组

// 指定范围生成元素全为整数的数组
// generate an array of random integers in a given range
const randomArrayInRange = (min, max, n) =>
  Array.from(
    { length: n },
    (v) => Math.floor(Math.random() * (max - min + 1)) + min
  );
const res = randomArrayInRange(1, 100, 10);
console.log(res);

23 字符串首字母大写

// 字符串首字母大写1
// capitalize a string 

function capitalize(str) {
  return `${str.charAt(0).toUpperCase()}${str.slice(1)}`
}

function capitalize2([first, ...rest]) {
  // 这里可以直接使用解构字符串
  return `${first.toUpperCase()}${rest.join("")}`;
}

const res2 = capitalize("hello world");
console.log(res2);

24 检查路径是否为绝对路径

const isRelativePath = (path) => !/^([a-z]+:)?[\\/]/i.test(path);

25 检查一个字符串是否有重复序列

// 检查一个字符串是否有重复序列
// # Check if a string consists of a repeated character sequence
function consistsRepeatedSubstring(str) {
  // indexOf 有两个参数(searchValue, fromIndex)
  return `${str}${str}`.indexOf(str, 1) !== str.length;
}

const res = consistsRepeatedSubstring('abc')
const res3 = consistsRepeatedSubstring('aaa')
console.log(res);
console.log(re4);

26 检查一个值是否是函数

// 检查一个值是否为函数
// check if a value is a function
function isFunction(v) {
  return [
    "[object Function]",
    "[object GeneratorFunction]",
    "[object AsyncFunction]",
    "[object Promise]",
  ].includes(Object.prototype.toString.call(v))
}

console.log(isFunction(function () {}));
console.log(isFunction(function* () {});
console.log(isFunction(async function () {});

27 组合函数

// 组合函数 
function pipe(...fns) {
  return (x) => fns.reduce((y, f) => f(y), x)
}

const lowercase = (str) => str.toLowerCase();
const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
const reverse = (str) => str.split('').reverse().join('');

const fn = pipe(lowercase, capitalize, reverse);
console.log(fn('Hello World'));