JS基础与进阶(持续更新)

·  阅读 197

1.函数柯里化

参数复用

function CurryingCheck(reg) {
  return function(text) {
    return reg.test(text)
  }
}
const hasNumber = CurryingCheck(/\d+/g)
const hasLetter = CurryingCheck(/[a-z]+/g)
console.log(hasNumber('abc1')) // true
console.log(hasLetter('1234')) // false
复制代码

循环调用

/*
 * 经典面试题,手写一个函数,使以下结果成立
 * add(1)(2)(3) => 6
 * add(1, 2, 3)(4) => 10
 * add(1, 2, 3)(4)(5) => 15
 */
function add() {
  let args = [...arguments]
  function fn() {
    args.push(...arguments)
    return fn
  }
  fn.toString = _ => args.reduce((prev, next) => prev + next)
  return fn
}
复制代码

2.函数自执行的几种方式

注意:自执行函数前面的JS语句必须以分号结尾。

! function () {  // 函数前加特殊符号 ! + - ~ . void
  console.log(1)
}();
(function () {
  console.log(2)
})();
(function () {
  console.log(3)
}());
复制代码

3.防抖

在指定时间连续调用防抖函数,防抖函数只执行一次。

1.立即执行版(即在指定时间内连续调用防抖函数,只执行第一次的定时函数)
2.非立即执行版(即在指定时间内连续调用防抖函数,只会执行最后一次的定时函数)

function debounce(fn, wait, immediate) {
  let T
  return function (...args) {
    if (T) {
      clearTimeout(T)
    } else if (immediate) {
      fn.apply(this, args)
    }
    T = setTimeout(() => {
      T = null
      if (!immediate) {
        fn.apply(this, args)
      }
    }, wait)
  }
}
复制代码

4.节流

如果连续执行节流函数,只会在每个指定的时间内执行一次

1.时间戳版

缺点:如果倒数第一次的调用和倒数第二次的调用时间间隔小于指定时间,则最后一次的调用不会执行

function throttle(fn, wait) {
  let time = 0
  return function (...args) {
    const nowTime = Date.now()
    if (nowTime - time >= wait) {
      fn.apply(this, args)
      time = nowTime
    }
  }
}
复制代码

2.定时器版

缺点:第一次触发,会在指定时间后才会执行

function throttle(fn, wait) {
  let T = null
  return function (...args) {
    if (!T) {
      T = setTimeout(() => {
        T = null
        fn.apply(this, args)
      }, wait)
    }
  }
}
复制代码

3.时间戳与定时器结合版
优点:有时我们更希望第一次触发立即执行处理函数,最后一次触发也执行一次处理函数

function throttle(fn, wait) {
  let time = 0
  let T = null
  return function (...args) {
    const nowTime = Date.now()
    const remaining = nowTime - time - wait
    if (T) clearTimeout(T)
    if (remaining >= 0) {
      fn.apply(this, args)
      time = nowTime
    } else {
      T = setTimeout(() => {
        fn.apply(this, args)
      }, wait)
    }
  }
}
复制代码

5.手写call、apply、bind 函数

1.call

Function.prototype.myCall = function (ctx, ...args) {
  let result
  if (ctx) {
    ctx._$ = this
    result = ctx._$(...args)
    delete ctx._$
  } else {
    result = this()
  }
  return result
}
复制代码

2.apply

Function.prototype.myapply = function(ctx, args){
  let result
  if (ctx) {
    ctx._$ = this
    result = ctx._$(...args)
    delete ctx._$
  } else {
    result = this()
  }
}
复制代码

3.bind

Function.prototype.mybind = function (ctx, ...args1) {
  let func = this
  return function (...args2) {
    if(!ctx){
      return func(...args2)
    }
    return func.call(ctx, ...args1, ...args2)
  }
}
复制代码
分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改