Skip to content
本页目录

常用方法

收集开发中的一些常用方法

环境判断

js
const UA = window.navigator.userAgent.toLowerCase()

// Android
const isAndroid = /android/.test(UA)

// IOS
const isIOS = /iphone|ipad|ipod|ios/.test(UA)

// 浏览器环境
const inBrowser = typeof window !== 'undefined'

// IE
const isIE = /msie|trident/.test(UA)

// Edge
const isEdge = UA.indexOf('edge/') > 0

// Chrome
const isChrome = /chrome\/\d+/.test(UA) && !isEdge

// 微信
const isWeChat = /micromessenger/.test(UA)

// 移动端
const isMobile = 'ontouchstart' in window

微信 api promise

微信 api promise
js
function promisify(fn) {
  return function (options) {
    return new Promise((resolve, reject) => {
      fn(
        Object.assign({}, options, {
          success: resolve,
          fail: reject
        })
      )
    })
  }
}

// 例 获取系统信息
promisify(wx.getSystemInfo)
  .then(res => {
    console.log('success', res)
  })
  .catch(err => {
    console.log('fail', err)
  })

验证 url 是否有效

js
function isUrl(string) {
  if (typeof string !== 'string') {
    return false
  }
  try {
    new URL(string)
    return true
  } catch (err) {
    return false
  }
}

isUrl('tongren') // false

isUrl('https://github.com/fangzhioo') // true
isUrl('https://a.b.c') // true

注意

该技巧只适用于一些验证不严格的场景,严格场景下可以使用这个 npm 包 —— is-url

提取身份证信息

提取身份证信息
js
/**
 * 获取身份证信息
 * @param {String} idCard 身份证号码
 * @param {String} separator 出生年月日的分割字符,默认为 `/`
 * @returns {Object} { age, birthday, gender }
 */
function getIdCardInfo(idCard, separator = '/') {
  if (!/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(idCard)) {
    throw Error(`${idCard}不是一个身份证号码`)
  }
  // 提取 idCard 中的字符
  const idSubstr = (s, e) => idCard.substr(s, e)
  // 拼接日期
  const splice = d => d.join(separator)
  // 获取出生年月日 性别(0 女 1 男)
  let birthday, gender
  if (idCard.length === 18) {
    birthday = splice([idSubstr(6, 4), idSubstr(10, 2), idSubstr(12, 2)])
    gender = idSubstr(-2, 1) & 1
  } else {
    birthday = splice(idSubstr(6, 2), idSubstr(8, 2), idSubstr(10, 2))
    gender = idSubstr(-1, 1) & 1
  }
  // 获取年龄(实岁)
  const birthDate = new Date(birthday)
  const newDate = new Date()
  const year = newDate.getFullYear()
  let age = year - birthDate.getFullYear()
  if (newDate < new Date(splice([year, birthday.substring(5)]))) {
    age--
  }
  return {
    age,
    birthday,
    gender
  }
}

一行代码取一个随机色

js
function getRandomColor() {
  return '#' + Math.floor(Math.random() * (1 << 24)).toString(16)
}

一行代码完成一个评级组件

js
function getRateStar(rate) {
  return '★★★★★☆☆☆☆☆'.slice(5 - rate, 10 - rate)
}

如何优雅的实现金钱格式化

比如:1234567890 --> 1,234,567,890

js
function formatCash(cash) {
  return cash.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

简单有效地让两个整数交换数值

常规方法 但是会存在整型数据溢出,对于 32 位字符最大表示 2147483647,大于这个数时,就失败了。

js
// 运用C的位操作
var a = 1,
  b = 2
a ^= b
b ^= a
a ^= b

最少的代码实现数组去重

js
;[...new Set([1, '1', 0, 2, 1, 3])]

短路表达式

大家都知道上面的&&与运算和||或运算,对应还有&|。这两者的区别在于,会不会判断执行第二个条件
比如,a&&b中,如果afalse,那么b部分便不会执行判断,直接输出false;但是对于a&b,如果afalse,还是会去判断执行b部分的结果(b也可能是个返回boolean类型的函数)。这里使用的短路表达式只能使用&&||,而不能使用&|

短路表达式
js
var a = b && 1
// 相当于
if (b) {
  a = 1
} else {
  a = b
}
// 还有或运算
var a = b || 1
// 相当于
if (b) {
  a = b
} else {
  a = 1
}

取出一个数字数组中的最大值和最小值

取出一个数字数组中的最大值和最小值
js
// 最小值
function getMinInArray(numbers) {
  return Math.min.apply(Math, numbers)
}
// 最大值
function getMaxInArray(numbers) {
  return Math.max.apply(Math, numbers)
}

快速排序

快速排序
js
function quickSort(arr) {
  var left = [],
    right = []
  var flag = arr.length / 2
  if (!flag) {
    return arr
  }
  var mid = arr.splice(flag, 1)
  arr.forEach(function (num) {
    num <= mid ? left.push(num) : right.push(num)
  })
  return quickSort(left).concat(mid, quickSort(right))
}

判断是否为数组、字符串

官方有提供 typeof 方法,但是有一定的局限性,没有办法完全判断。比如,typeof {}typeof [] 的结果都是 object,就无法区分具体是对象,还是数组。
其实 JavaScript 的原型链告诉我们,为什么输出的都是object,这里就不拓展了。

判断是否为数组、字符串
js
// 判断是否为数组
function isArray(arg) {
  return Object.prototype.toString.call(arg) !== '[object Array]'
}
// 判断是否为字符串
function isString(arg) {
  return Object.prototype.toString.call(arg) !== '[object String]'
}

生成水印

水印生成
js
const id = 'ab1814913b0fd86c70557424f'

// 页面添加水印效果
const setWatermark = (str: string) => {
  try {
    const wDom = document.getElementById(id)
    if (!str && wDom) {
      document.body.removeChild(<HTMLElement>document.getElementById(id))
      return
    }
    if (document.getElementById(id) !== null) document.body.removeChild(<HTMLElement>document.getElementById(id))
    const can = document.createElement('canvas')
    can.width = 200
    can.height = 130
    const cans: any = can.getContext('2d')
    cans.rotate((-20 * Math.PI) / 180)
    cans.font = '16px Vedana'
    cans.fillStyle = 'rgba(200, 200, 200, 0.30)'
    cans.textBaseline = 'Middle'
    cans.fillText(str, can.width / 10, can.height / 2)
    const div = document.createElement('div')
    div.id = id
    div.style.pointerEvents = 'none'
    div.style.top = '15px'
    div.style.left = '0px'
    div.style.position = 'fixed'
    div.style.zIndex = '10000000'
    div.style.width = '100vw'
    div.style.height = '100vh'
    div.style.background = `url(${can.toDataURL('image/png')}) left top repeat`
    document.body.appendChild(div)
    return id
  } catch (error) {
    console.warn('Watermark Setting Error:', error)
  }
}


/**
 * 页面添加水印效果
 * @method set 设置水印
 * @method del 删除水印
 */
const watermark = {
  // 设置水印
  set: (str: string) => {
    return setWatermark(str)
  },
  // 删除水印
  del: () => {
    if (document.getElementById(id) !== null) document.body.removeChild(<HTMLElement>document.getElementById(id))
  },
}


// 导出方法
export default watermark;

如有转载或 CV 的请标注本站原文地址