手撕代码

Frank
  • 前端面试
  • 面试复盘
  • 手撕代码
大约 2 分钟约 613 字...

手撕 instanceOf

function instance_of(L, R) {
  let prototype = R.prototype
  while (true) {
    if (L === null) {
      return false
    } else if (prototype === L.__proto__) {
      return true
    }
    L = L.__proto__
  }
}
console.log(instance_of([1, 2, 3], Function)) // false

借用链表数据结构:

const instance_of = (A, B) => {
  let p = A
  while (p) {
    if (p.__proto__ === B.prototype) {
      return true
    }
    p = p.__proto__
  }
  return false
}
console.log(instance_of([1, 2, 3], Function)) // false
console.log(instance_of([1, 2, 3], Array)) // true

手撕函数节流

理解: 在函数需要频繁触发时:函数执行一次后,只有大于设定的执行周期后才会执行第二次

适合多次事件按时间做平均分配触发

场景:窗口调整(resize),页面滚动(scroll),DOM 元素的拖拽功能实现(mousemove,drag),抢购疯狂点击(click)

手撕

function throttle(callback, wait) {
  let timer = null
  return function (e) {
    if (timer) {
      return
    }
    timer = setTimeout(() => {
      callback.call(this, e)
      timer = null
    }, wait)
  }
}

使用

window.addEventListener(
  'scroll',
  throttle(function (e) {
    console.log(this, e)
  }, 2000)
)

手撕函数防抖

理解

在函数需要频繁触发时,在规定时间内,只让最后一次生效,前面的不生效

适合多次事件一次响应

场景:输入框实时搜索联想(change,keyup,keydown)

手撕

function debounce(callback, time) {
  let timer = null
  // 闭包
  return function (e) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      callback.call(this, e)
      // 清空定时器
      timer = null
    }, time)
  }
}

使用

<input type="text" id="input" />
<script type="text/javascript">
  const input = document.getElementById('input')
  input.onkeydown = debounce(function (e) {
    console.log(e.keyCode)
  }, 1000)
</script>

深拷贝

JS 深拷贝总结open in new window

function deepClone(obj = {}) {
  if (typeof obj !== 'object' || obj == null) {
    // obj == null 相当于 obj === undefined || obj === null
    // obj 是 null , 或者不是对象或数组直接返回
    return obj
  }
  // 初始化返回结果
  let result
  if (obj instanceof Array) {
    result = []
  } else {
    result = {}
  }
  for (let key in obj) {
    // 保证key不是obj的原型属性
    if (obj.hasOwnProperty(key)) {
      // 递归
      result[key] = deepClone(obj[key])
    }
  }
  return result
}

手撕冒泡排序

function handleArr(arr) {
  for (var i = 0; i < arr.length; i++) {
    for (var j = arr.length - 1; j >= i; j--) {
      if (arr[j] < arr[j - 1]) {
        ;[arr[j - 1], arr[j]] = [arr[j], arr[j - 1]]
      }
    }
  }
  return arr
}
const arr = [1, 3000, -1333, 33]
console.log(handleArr(arr))

手写 new

function mynew(Func, ...args) {
  // 1.创建一个新对象
  const obj = {}
  // 2.新对象原型指向构造函数原型对象
  obj.__proto__ = Func.prototype
  // 3.将构建函数的this指向新对象
  let result = Func.apply(obj, args)
  // 4.根据返回值判断:
  return result instanceof Object ? result : obj
}
上次编辑于:
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.1