欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

面试题中手写代码的题目

程序员文章站 2022-06-09 18:45:08
...

数组去重
方法一

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)
    }
  }
}
相关标签: js面试题