面试题中手写代码的题目

数组去重
方法一

export function uniqueArray(arr: any[]) {
  return arr.filter((item, index) => arr.indexOf(item) === index)
}
console.log(uniqueArray([1, 2, 3, 2, 1, 3, 4, 5, 6, 3, 8]))
// [1, 2, 3, 4, 5, 6, 8]

方法二

export function uniqueArray(arr: any[]) {
  const newArr = arr.sort()
  let result = [newArr[0]]
  for (let i = 1; i < newArr.length; i++) {
    newArr[i] !== newArr[i - 1] && result.push(newArr[i])
  }
  return result
}
console.log(uniqueArray([1, 2, 3, 2, 1, 3, 4, 5, 6, 3, 8]))
// [1, 2, 3, 4, 5, 6, 8]

js深拷贝

export function deepClone (obj: Object | any) {
  let result: any = {}
  for (let k in obj) {
    let typeStr = Object.prototype.toString.call(obj[k])
                .match(/\[object (.*?)\]/)[1].toLowerCase();
    switch (typeStr) {
      case 'object':
        result[k] = deepClone(obj[k])
        break
      case 'array':
        result[k] = obj[k].slice()
        break
      default:
        result[k] = obj[k]
    }
  }
  return result
}

实现一个 instanceof
instanceof 的原理就是判断这个变量是否来自于某一个构造函数

在这里插入代码片export function selfInstanceOf (left, right) {
  while (true) {
    if (left === null) return false
    if (left === right) return true
    if (left.__proto__ === right.prototype) return true
    left = left.__proto__
  }
}

// test
selfInstanceOf({}, Object)    // true
selfInstanceOf({}, Array)     // false
selfInstanceOf([], Array)     // true
selfInstanceOf([], Object)     // true

const Fn = function() {}
const a = new Fn()
selfInstanceOf(a, Fn)     // true
selfInstanceOf(a, Object)     // true

手写 Object.create 方法
科里化函数
通过判断参数是否符合实际方法所需参数的数量进行执行函数或者继续递归判断

export function curry (fn: Function) {
  const _this = this
  const args = Array.from(arguments).slice(1)
  // fn.length 属性指明函数的形参个数。
  const len = fn.length

  return function () {
    const _args = Array.from(arguments)
    args.push(..._args)
    if (args.length < len) {
      return curry.call(_this, fn, ...args)
    }

    return fn.apply(_this, args)
  }
}

// test
const addCur = function (a, b, c) {
  console.log('a + b + c', a + b + c)
}

const reduceCur = function (a, b, c) {
  console.log('a - b - c', a - b - c)
} 

const add = curry(addCur, 2)
s(1)(2)   // a + b + c 6
s(1, 3)   // a + b + c 6

const reduce = curry(reduceCur)
reduce(1)(2)(3)    // a - b - c -1
reduce(1, 2, 3)    // a - b - c -3

compose
类似react中组件, compose(fn1, fn2, fn3) (…args) = > fn1(fn2(fn3(…args)))

export function compose (...fn: Function[]) {
  return function (...args: any) {
    return fn.reduceRight((prevResult, currentFn) => {
      return currentFn.call(this, ...prevResult)
    }, args)
  }
}

实现一个 instanceof
instanceof 的原理就是判断这个变量是否来自于某一个构造函数

export function selfInstanceOf (left, right) {
  while (true) {
    if (left === null) return false
    if (left === right) return true
    if (left.__proto__ === right.prototype) return true
    left = left.__proto__
  }
}

// test
selfInstanceOf({}, Object)    // true
selfInstanceOf({}, Array)     // false
selfInstanceOf([], Array)     // true
selfInstanceOf([], Object)     // true

const Fn = function() {}
const a = new Fn()
selfInstanceOf(a, Fn)     // true
selfInstanceOf(a, Object)     // true

手写bind
注意:bind方法只是返回一个可执行函数,执行需要由用户自己执行返回的函数

Function.prototype.selfBind = function (context: Window = window) {
  const fn = this
  const ctx = context || {}
  const arg = Array.from(arguments).slice(1)
  return function () {
    fn.call(ctx, ...arg)
  }
}

foo.getA.selfBind(null, 'selfBind', 22)()

// prop: undefined
// name: selfBind
// age: 22
// -------------------

手写apply
apply同样也是返回一个执行结果,只是第二个参数为数组

Function.prototype.selfApply = function (context: Window = window) {
  const ctx = context || {}
  ctx.fn = this
  const arg = Array.from(arguments).slice(1)[0]
  const result = ctx.fn(...arg)
  delete ctx.fn
  return result
}

// 接着call的对象信息执行代码
foo.getA.selfApply(bar, ['selfApply', 22])

// prop: this is bar
// name: selfApply
// age: 22
// -------------------

手写call
call返回一个执行结果,第二个及以后的参数为执行函数的参数

Function.prototype.selfCall = function (context: Window = window) {
  const ctx = context || {}
  ctx.fn = this
  const args = Array.from(arguments).slice(1)
  const result = ctx.fn(args)
  delete ctx.fn
  return result
}

const bar = {
  a: 'this is bar'
}
const foo = {
  a: 1,
  getA: function (name, age = 0) {
    console.log(`prop: ${this.a}`)
    console.log(`name: ${name}`)
    console.log(`age: ${age}`)
    console.log('-------------------')
  }
}

foo.getA.selfCall(bar, 'selfCall')

// prop: this is bar
// name: selfCall
// age: 0
// -------------------

JS节流函数
节流的概念为多次点击的过程中只会在每次大于wait等待时长执行方法

export function throttle (fn: Function, wait: number = 1000) {
  let prev: number = +new Date()

  return function () {
    const now: number = +new Date
    if (now - prev > wait) {
      fn.apply(this, arguments)
      prev = +new Date()
    }
  }
}

JS防抖函数
基本的防抖函数

export function debounce (fn: Function, wait: number = 1000) {
  let t: any
  return function () {
    const _this = this
    t && clearTimeout(t)

    t = setTimeout(function() {
      fn.apply(_this, arguments)
    }, wait)
  }
}

添加 immediate 参数

export function debounce (fn: Function, wait: number = 1000, immediate: boolean = true) {
  let t: any
  return function () {
    const _this = this
    const _arg = arguments
    t && clearTimeout(t)

    if (immediate) {
      let isDo = !t
      t = setTimeout(function() {
        t = null
      }, wait)
      if (isDo) {
        fn.apply(_this, _arg)
      }
    } else {
      t = setTimeout(function() {
        fn.apply(_this, _arg)
      }, wait)
    }
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值