Skip to content

1~100的完全平方数

javascript
{
  // 1~100的完全平方数
  function isSqrt(n) {
    for (var i = 1; n > 0; i += 2) {
      n -= i
    }
    return 0 == n
  }
  for (var j = 1; j <= 100; j++) {
    if (isSqrt(j)) {
      console.log(j) // 1 4 9 16 25 36 49 64 81 100
    }
  }
}

统计数组中相同项的个数

javascript
{
  // 统计数组中相同项的个数
  var cars = [
    'xiaoming',
    'xiaohong',
    'xiaohong',
    'xiaohong',
    'xiaolv',
    'xiaolan',
    'xiaohei',
  ]
  var carsObj = cars.reduce(function (obj, name) {
    obj[name] = obj[name] ? ++obj[name] : 1
    return obj
  }, {})
  console.log(carsObj) // { xiaoming: 1, xiaohong: 3, xiaolv: 1, xiaolan: 1, xiaohei: 1 }
}

判断数组或者一个字符串中出现次数最多的元素及其出现的次数

javascript
{
  // 判断数组或者一个字符串中出现次数最多的元素及其出现的次数
  function maxCountElement(arr) {
    var obj = {}
    for (var i = 0; i < arr.length; i++) {
      var key = arr[i]
      if (obj[key]) {
        obj[key]++
      } else {
        obj[key] = 1
      }
    }
    var maxCount = 0
    var maxElement = arr[0]
    var eq = []
    for (var key in obj) {
      if (maxCount < obj[key]) {
        maxCount = obj[key]
        maxElement = key
        eq.length = 0
      } else if (maxCount === obj[key]) {
        eq.push(key)
      }
    }
    if (eq.length > 0) {
      for (var j = 0; j < eq.length; j++) {
        maxElement += ',' + eq[j]
      }
    }
    return `该数组中出现次数最多的元素:${maxElement},出现了:${maxCount}次`
  }
  var arr = [1, 2, 2, 2, 3, 3, 3, 4, 5, 6]
  var res = maxCountElement(arr)
  console.log(res) // 该数组中出现次数最多的元素:2,3,出现了:3次
}

判断回文字符串

javascript
{
  // 实现一个函数,判断输入是不是回文字符串(在我的理解,如果将一个字符串翻转过来,能和原字符串完全相等,那么就可以称之为“回文”)

  // one
  function Palindrome1(input) {
    if (typeof input !== 'string') return false
    return input.split('').reverse().join('') === input
  }

  // two
  function Palindrome2(line) {
    line += ''
    for (var i = 0, j = line.length - 1; i < j; i++, j--) {
      if (line.charAt(i) !== line.charAt(j)) {
        return false
      }
    }
    return true
  }
}

trim

javascript
{
  String.prototype.trim = function () {
    return this.replace(/^\s+/, '').replace(/\s+$/, '')
  }
}

{
  // 正则实现trim()功能
  function myTrim(str) {
    let reg = /^\s+|\s+$/g
    return str.replace(reg, '')
  }
  let str = '    wcd    '
  console.log(myTrim(str)) // wcd
}

检测平台(设备)类型

javascript
{
  // 检测平台(设备)类型
  let isWechat = /micromessenger/i.test(navigator.userAgent),
    isWeibo = /weibo/i.test(navigator.userAgent),
    isQQ = /qq\//i.test(navigator.userAgent),
    isIOS = /(iphone|ipod|ipad|ios)/i.test(navigator.userAgent),
    isAndroid = /android/i.test(navigator.userAgent)
}

获取 URL 的中参数

javascript
{
  // 获取 URL 的中参数 (推荐 https://github.com/derek-watson/jsUri)
  // 正则
  function getQueryString(name) {
    var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
    var r = window.location.search.substr(1).match(reg) //获取url中"?"符后的字符串并正则匹配
    var context = ''
    if (r != null) context = r[2]
    reg = null
    r = null
    return context == null || context == '' || context == 'undefined' ? '' : context
  }
  // such as:
  // alert(GetQueryString("参数名1"));
  // alert(GetQueryString("参数名2"));
  // alert(GetQueryString("参数名3"));

  // split拆分法
  function GetRequest() {
    var url = location.search //获取url中"?"符后的字串
    var theRequest = new Object()
    if (url.indexOf('?') != -1) {
      var str = url.substr(1)
      strs = str.split('&')
      for (var i = 0; i < strs.length; i++) {
        theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1])
      }
    }
    return theRequest
  }
  var Request = new Object()
  Request = GetRequest()
  // var 参数1,参数2,参数3,参数N;
  // 参数1 = Request['参数1'];
  // 参数2 = Request['参数2'];
  // 参数3 = Request['参数3'];
  // 参数N = Request['参数N'];

  // 修改 URL 的中某个参数值
  //替换指定传入参数的值,paramName为参数,replaceWith为新值
  function replaceParamVal(paramName, replaceWith) {
    var oUrl = this.location.href.toString()
    var re = eval('/(' + paramName + '=)([^&]*)/gi')
    var nUrl = oUrl.replace(re, paramName + '=' + replaceWith)
    this.location = nUrl
    window.location.href = nUrl
  }

  /**
   * 指定参数名称,返回该参数的值 或者 空字符串
   * 不指定参数名称,返回全部的参数对象 或者 {}
   * 如果存在多个同名参数,则返回数组
   */
  function getUrlParam(url, key) {
    var arr = {}
    url.replace(/\??(\w+)=(\w+)&?/g, function (match, matchKey, matchValue) {
      if (!arr[matchKey]) {
        arr[matchKey] = matchValue
      } else {
        var temp = arr[matchKey]
        arr[matchKey] = [].concat(temp, matchValue)
      }
    })
    if (!key) {
      return arr
    } else {
      for (ele in arr) {
        if ((ele = key)) {
          return arr[ele]
        }
      }
      return ''
    }
  }
}

H5(ios)-在点击输入框,出现键盘后,弹出层被顶上去,而光标还停留在原处,即出现错位情况

javascript
{
  // 单个input(textarea)
  $('input.van-field__control, textarea.van-field__control').blur(function () {
    setTimeout(function () {
      var currentPosition = document.documentElement.scrollTop || document.body.scrollTop
      window.scrollTo(0, currentPosition) //页面向上滚动
    }, 200)
  })

  // 多个input(textarea)
  $(function () {
    var setTimerTop = 0
    $(document)
      .on('blur', 'input.van-field__control, textarea.van-field__control', function () {
        event.preventDefault()
        setTimerTop = setTimeout(function () {
          window.scrollBy(0, 5) // 页面向上滚动
          window.scrollBy(0, -5)
        }, 500)
      })
      .on('focus', 'input.van-field__control, textarea.van-field__control', function () {
        clearTimeout(setTimerTop)
      })
  })

  // 多个input(textarea)-iframe情况
  $(function () {
    var setTimerTop = 0
    $(document)
      .on('blur', 'input.van-field__control, textarea.van-field__control', function () {
        event.preventDefault()
        setTimerTop = setTimeout(function () {
          parent.scrollBy(0, 5) // 页面向上滚动
          parent.scrollBy(0, -5)
          $('#hide-area-cb').focus()
        }, 500)
      })
      .on('focus', 'input.van-field__control, textarea.van-field__control', function () {
        clearTimeout(setTimerTop)
      })
      .on('focus', 'input.van-field__control[disabled]', function () {
        setTimerTop = setTimeout(function () {
          parent.scrollBy(0, 5) // 页面向上滚动
          parent.scrollBy(0, -5)
        }, 500)
      })
  })
}

判断类型

javascript
// 判断类型
function toType(obj) {
  return {}.toString
    .call(obj)
    .match(/\s([a-zA-Z]+)/)[1]
    .toLowerCase()
}

对象判空

注:永远不要使用构造函数创建对象

ts
function isEmpty1(obj: Record<string, any>): boolean {
  return JSON.stringify(obj) === '{}'
}

function isEmpty2(obj: Record<string, any>): boolean {
  return Object.keys(obj).length === 0
}

function isEmpty3(obj: Record<string, any>): boolean {
  return Object.getOwnPropertyNames(obj).length === 0
}

function isEmpty4(obj: Record<string, any>): boolean {
  let flag = true
  for (const key in obj) {
    if (key) {
      flag = false
      break
    }
  }
  return flag
}

function isEmpty5(obj: Record<string, any>): boolean {
  return Reflect.ownKeys(obj).length === 0
}

function isEmpty6(obj: Record<string, any>): boolean {
  return (
    Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)).length === 0
  )
}

function isEmpty7(value: any): boolean {
  return value && Object.keys(value).length === 0 && value.constructor === Object
}

function isEmpty8(value: any): boolean {
  return (
    Object.prototype.toString.call(value) === '[object Object]' &&
    JSON.stringify(value) === '{}'
  )
}

const key = Symbol('key')
const obj: Record<symbol, string> = {
  [key]: 'value',
}

console.log('[1], obj is empty:', isEmpty1(obj))
console.log('[2], obj is empty:', isEmpty2(obj))
console.log('[3], obj is empty:', isEmpty3(obj))
console.log('[4], obj is empty:', isEmpty4(obj))
console.log('[5], obj is empty:', isEmpty5(obj))
console.log('[6], obj is empty:', isEmpty6(obj))
console.log('[7], obj is empty:', isEmpty7(obj))
console.log('[8], obj is empty:', isEmpty8(obj))

// [1], obj is empty: true
// [2], obj is empty: true
// [3], obj is empty: true
// [4], obj is empty: true
// [5], obj is empty: false
// [6], obj is empty: false
// [7], obj is empty: true
// [8], obj is empty: true
js
// Lodash
_.isEmpty({})
js
// jQuery
jQuery.isEmptyObject({})

函数防抖

javascript
{
  // 简单 函数防抖
  function debounce(method, wait) {
    let timeout
    // args为返回函数调用时传入的参数,传给method
    return function (...args) {
      let context = this
      if (timeout) {
        clearTimeout(timeout)
      }
      timeout = setTimeout(() => {
        // args是一个数组,所以使用fn.apply
        // 也可写作method.call(context, ...args)
        method.apply(context, args)
      }, wait)
    }
  }

  // 完整 函数防抖
  function debounce(method, wait, immediate) {
    let timeout
    // debounced函数为返回值
    // 使用Async/Await处理异步,如果函数异步执行,等待setTimeout执行完,拿到原函数返回值后将其返回
    // args为返回函数调用时传入的参数,传给method
    let debounced = function (...args) {
      return new Promise((resolve) => {
        // 用于记录原函数执行结果
        let result
        // 将method执行时this的指向设为debounce返回的函数被调用时的this指向
        let context = this
        // 如果存在定时器则将其清除
        if (timeout) {
          clearTimeout(timeout)
        }
        // 立即执行需要两个条件,一是immediate为true,二是timeout未被赋值或被置为null
        if (immediate) {
          // 如果定时器不存在,则立即执行,并设置一个定时器,wait毫秒后将定时器置为null
          // 这样确保立即执行后wait毫秒内不会被再次触发
          let callNow = !timeout
          timeout = setTimeout(() => {
            timeout = null
          }, wait)
          // 如果满足上述两个条件,则立即执行并记录其执行结果
          if (callNow) {
            result = method.apply(context, args)
            resolve(result)
          }
        } else {
          // 如果immediate为false,则等待函数执行并记录其执行结果
          // 并将Promise状态置为fullfilled,以使函数继续执行
          timeout = setTimeout(() => {
            // args是一个数组,所以使用fn.apply
            // 也可写作method.call(context, ...args)
            result = method.apply(context, args)
            resolve(result)
          }, wait)
        }
      })
    }

    // 在返回的debounced函数上添加取消方法
    debounced.cancel = function () {
      clearTimeout(timeout)
      timeout = null
    }

    return debounced
  }
}

生成 -0

javascript
// one

// 首先创建一个8位的ArrayBuffer
const buffer = new ArrayBuffer(8)
// 创建DataView对象操作buffer
const dataView = new DataView(buffer)
// 将第1个字节设置为0x80,即最高位为1
dataView.setUint8(0, 0x80)
// 将buffer内容当做Float64类型返回
console.log(dataView.getFloat64(0)) // -0

// two
console.log(0 * -1) // -0

reduce

javascript
{
  // 对后端返回的列表数据进行相同数据整合处理
  let oldList = [
    { id: 111, date: '05-25', list: [1, 2, 3] },
    { id: 222, date: '05-26', list: [4, 5] },
    { id: 111, date: '05-25', list: [4, 5] },
  ]
  function formatList() {
    return Array.from(
      oldList.reduce((dict, item) => {
        if (dict.has(item.id)) {
          dict.get(item.id).list.push(...item.list)
        } else {
          dict.set(item.id, {
            id: item.id,
            date: item.date,
            list: [...item.list],
          })
        }
        return dict
      }, new Map())
    ).map((item) => ({
      date: item[1].date,
      id: item[1].id,
      list: item[1].list,
    }))
  }
  console.log(formatList())
  // [
  //     { id: 111, date: "05-25", list: [1, 2, 3, 4, 5] },
  //     { id: 222, date: "05-26", list: [4, 5] }
  // ];

  // 数组list去重
  const data = [
    { name: 'Kris', age: '24' },
    { name: 'Andy', age: '25' },
    { name: 'Kitty', age: '25' },
    { name: 'Andy', age: '25' },
    { name: 'Kitty', age: '25' },
    { name: 'Andy', age: '25' },
    { name: 'Kitty', age: '25' },
  ]

  let newData = Object.values(
    data.reduce((prev, cur, idx) => {
      let obj = {}
      const { name } = cur
      obj[name] = cur
      return {
        ...prev,
        ...obj,
      }
    }, {})
  )
  console.log(newData)
}

{
  /**
   * reduce方法同时实现map和filter
   * 需求:假设现在有一个数列,你希望更新它的每一项(map的功能)然后筛选出一部分(filter的功能)。如果是先使用map然后filter的话,你需要遍历这个数组两次。 在下面的代码中,我们将数列中的值翻倍,然后挑选出那些大于50的数
   */
  const numbers = [10, 20, 30, 40]
  const doubledOver50 = numbers.reduce((finalList, num) => {
    num = num * 2
    if (num > 50) {
      finalList.push(num)
    }
    return finalList
  }, [])
  console.log(doubledOver50) // [ 60, 80 ]
}

实现数字金额转大写金额

javascript
function digitUppercase(n) {
  let fraction = ['角', '分']
  let digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
  let unit = [
    ['元', '万', '亿'],
    ['', '拾', '佰', '仟'],
  ]
  let head = n < 0 ? '欠' : ''
  n = Math.abs(n)
  let s = ''
  for (let i = 0; i < fraction.length; i++) {
    s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(
      /零./,
      ''
    )
  }
  s = s || '整'
  n = Math.floor(n)
  for (let k = 0; k < unit[0].length && n > 0; k++) {
    let p = ''
    for (let j = 0; j < unit[1].length && n > 0; j++) {
      p = digit[n % 10] + unit[1][j] + p
      n = Math.floor(n / 10)
    }
    s = `${p.replace(/(零.)*$/, '').replace(/^$/, '零')}${unit[0][k]}${s}`
  }
  return `${head}${s
    .replace(/(零.)*零元/, '元')
    .replace(/(零.)+/g, '零')
    .replace(/^$/, '零元整')}`
}

console.log(digitUppercase(7682.01)) // 柒仟陆佰捌拾贰元壹分
console.log(digitUppercase(7682)) // 柒仟陆佰捌拾贰元整
console.log(digitUppercase(951434677682.0)) // 玖仟伍佰壹拾肆亿叁仟肆佰陆拾柒万柒仟陆佰捌拾贰元整

function noToChinese(num) {
  if (!/^\d*(\.\d*)?$/.test(num)) return

  var digit = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖')
  var unit = new Array('', '拾', '佰', '仟', '萬', '億', '点', '')
  var a = ('' + num).replace(/(^0*)/g, '').split('.'),
    k = 0,
    re = ''
  for (var i = a[0].length - 1; i >= 0; i--) {
    switch (k) {
      case 0:
        re = unit[7] + re
        break
      case 4:
        if (!new RegExp('0{4}\\d{' + (a[0].length - i - 1) + '}$').test(a[0]))
          re = unit[4] + re
        break
      case 8:
        re = unit[5] + re
        unit[7] = unit[5]
        k = 0
        break
    }
    if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0)
      re = digit[0] + re
    if (a[0].charAt(i) != 0) re = digit[a[0].charAt(i)] + unit[k % 4] + re
    k++
  }
  // 处理小数部分
  if (a.length > 1) {
    re += unit[6]
    for (var i = 0; i < a[1].length; i++) re += digit[a[1].charAt(i)]
  }
  return re
}

返回字符串的字节长度

javascript
function byteSize(str) {
  return new Blob([str]).size
}
console.log(byteSize('Hello World')) // 11

平均数

javascript
// 平均数
const average = (...nums) => nums.reduce((acc, val) => acc + val, 0) / nums.length
console.log(average(...[1, 2, 3])) // 2
console.log(average(1, 2, 3)) // 2

日期

javascript
// 当前日期天数
const dayOfYear = (date) =>
  Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24)
console.log(dayOfYear(new Date())) // 302

// 返回日期间的天数
const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 3600 * 24)
console.log(getDaysDiffBetweenDates(new Date('2019-01-01'), new Date('2019-10-29'))) // 301

解析有效日期

iOS 解析 YYYY-MM-DD HH:mm:ss 这种日期格式会报错 Invalid Date,Android 无问题 查看开发手册发现可用:YYYY/MM/DD HH:mm:ss,那么需替换其中的 - 为 /

javascript
const date = '2021-02-05 10:39:00'
new Date(date.replace(/\-/g, '/'))

首(每个)字母大、小写

javascript
// 首字母大写
const capitalize = ([first, ...rest]) => first.toUpperCase() + rest.join('')
console.log(capitalize('fooBar')) // FooBar
console.log(capitalize('fooBar', true)) // FooBar

// 首字母小写
const decapitalize = ([first, ...rest]) => first.toLowerCase() + rest.join('')
console.log(decapitalize('FooBar')) // fooBar
console.log(decapitalize('FooBar')) // fooBar

// 每个单词首字母大写
const capitalizeEveryWord = (str) => str.replace(/\b[a-z]/g, (char) => char.toUpperCase())
console.log(capitalizeEveryWord('hello world!')) // 'Hello World!'

平滑滚动至顶部

javascript
const scrollToTop = () => {
  const c = document.documentElement.scrollTop || document.body.scrollTop
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop)
    window.scrollTo(0, c - c / 8)
  }
}

滚动到指定元素区域

javascript
const smoothScroll = (element) =>
  document.querySelector(element).scrollIntoView({
    behavior: 'smooth',
  })
smoothScroll('#fooBar')

深克隆

javascript
const clone = (parent) => {
  // 维护两个储存循环引用的数组
  const parents = []
  const children = []

  const _clone = (parent) => {
    if (parent === null) return null
    if (typeof parent !== 'object') return parent

    let child, proto

    if (isType(parent, 'Array')) {
      // 对数组做特殊处理
      child = []
    } else if (isType(parent, 'RegExp')) {
      // 对正则对象做特殊处理
      child = new RegExp(parent.source, getRegExp(parent))
      if (parent.lastIndex) child.lastIndex = parent.lastIndex
    } else if (isType(parent, 'Date')) {
      // 对Date对象做特殊处理
      child = new Date(parent.getTime())
    } else {
      // 处理对象原型
      proto = Object.getPrototypeOf(parent)
      // 利用Object.create切断原型链
      child = Object.create(proto)
    }

    // 处理循环引用
    const index = parents.indexOf(parent)

    if (index != -1) {
      // 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象
      return children[index]
    }
    parents.push(parent)
    children.push(child)

    for (let i in parent) {
      // 递归
      child[i] = _clone(parent[i])
    }

    return child
  }
  return _clone(parent)
}

{
  const isComplexDataType = (obj) =>
    (typeof obj === 'object' || typeof obj === 'function') && obj !== null

  const deepClone = function (obj, hash = new WeakMap()) {
    // 日期对象直接返回一个新的日期对象
    if (obj.constructor === Date) {
      return new Date(obj)
    }

    //正则对象直接返回一个新的正则对象
    if (obj.constructor === RegExp) {
      return new RegExp(obj)
    }

    //如果循环引用了就用 weakMap 来解决
    if (hash.has(obj)) {
      return hash.get(obj)
    }

    let allDesc = Object.getOwnPropertyDescriptors(obj)

    //遍历传入参数所有键的特性
    let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)

    //继承原型链
    hash.set(obj, cloneObj)

    for (let key of Reflect.ownKeys(obj)) {
      cloneObj[key] =
        isComplexDataType(obj[key]) && typeof obj[key] !== 'function'
          ? deepClone(obj[key], hash)
          : obj[key]
    }

    return cloneObj
  }
}

Other

javascript
{
  for (var i = 1; i <= 3; i++) {
    console.log(i) // 1 2 3
    // setTimeout(function () {
    //   console.log(i); // 4 4 4
    // }, 0);
  }
}

{
  var a = null
  console.log(typeof a) // object
}

{
  var a = 100

  function test() {
    console.log(a) // 100
    a = 10
    console.log(a) // 10
  }
  test()
  console.log(a) // 10
}

{
  var uname = 'jack'
  function change() {
    console.log(uname) // undefined
    var uname = 'wcd'
    console.log(uname) // wcd
  }
  change()
}

{
  function createBase(baseNumber) {
    return function (N) {
      return baseNumber + N
    }
  }
  let addSix = createBase(6)
  console.log(addSix(10)) // 16
  console.log(addSix(21)) // 27
}

{
  var name = 'global'
  var obj = {
    name: 'obj',
    sex: function () {
      this.name = 'wcd'
      return function () {
        return this.name
      }
    },
  }
  console.log(obj.sex().call(this)) // undefined
  console.log(obj.sex().call(obj)) // wcd
}

{
  /**
   * 需求:假设需要对字符串进行字符长度限制
   * str为字符串,len为长度
   */
  function setString(str, len) {
    var strlen = 0
    var s = ''
    for (var i = 0; i < str.length; i++) {
      if (str.charCodeAt(i) > 128) {
        strlen += 2
      } else {
        strlen++
      }
      s += str.charAt(i)
      if (strlen >= len) {
        return s + '...'
      }
    }
    return s
  }
}

{
  const isType = (obj, type) => {
    if (typeof obj !== 'object') return false
    const typeString = Object.prototype.toString.call(obj)
    let flag
    switch (type) {
      case 'Array':
        flag = typeString === '[object Array]'
        break
      case 'Date':
        flag = typeString === '[object Date]'
        break
      case 'RegExp':
        flag = typeString === '[object RegExp]'
        break
      default:
        flag = false
    }
    return flag
  }
  const getRegExp = (re) => {
    var flags = ''
    if (re.global) flags += 'g'
    if (re.ignoreCase) flags += 'i'
    if (re.multiline) flags += 'm'
    return flags
  }
}