JavaScript編碼能力

1.多種方式實現(xiàn)數(shù)組去重、扁平化、對比優(yōu)缺點

數(shù)組去重

// 普通數(shù)組去重
function dedupe(arr) {
  let rets = []
  for (let i = 0; i < arr.length; i++) {
    if (!rets.includes(arr[i])) rets.push(arr[i])
  }
  return rets
}

function dedupe(arr) {
  let rets = []
  arr &&
    arr.forEach(function(item) {
      if (!rets.includes(item)) rets.push(item)
    })
  return rets
}

function dedupe(array) {
  return [...new Set(array)]
}

// 對象數(shù)組去重 key為獨立唯一標(biāo)識
function unique(arr, key) {
  const hash = {}
  const res = []
  for (let i = 0; i < arr.length; i++) {
    if (!hash[arr[i][key]]) {
      res.push(arr[i])
      hash[arr[i][key]] = true
    }
  }
  return res
}

const unique = (arr, key) => {
  let hash = {}
  return arr.reduce((accumulator, currentValue) => {
    hash[currentValue[key]]
      ? ''
      : (hash[currentValue[key]] = true && accumulator.push(currentValue))
    return accumulator
  }, [])
}

扁平化

function flatten(arr) {
  let rets = []
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      rets = rets.concat(flatten(arr[i]))
    } else {
      rets.push(arr[i])
    }
  }
  return rets
}

function flatten(arr) {
  let rets = []
  arr &&
    arr.forEach(item => {
      if (Array.isArray(item)) {
        rets = rets.concat(flatten(item))
      } else {
        rets.push(item)
      }
    })
  return rets
}

const flatten = arr =>
  arr.reduce(
    (accumulator, currentValue) =>
      accumulator.concat(
        Array.isArray(currentValue) ? flatten(currentValue) : currentValue
      ),
    []
  )

2.多種方式實現(xiàn)深拷貝、對比優(yōu)缺點

// 乞丐版
function deepCopy(obj) {
  return JSON.parse(JSON.stringgify(obj))
}

// 面試夠用版
function deepCopy(obj) {
  let result = obj.constructor === Array ? [] : {}
  for (let i in obj) {
    result[i] = typeof obj[i] === 'object' ? deepCopy(obj[i]) : obj[i]
  }
  return result
}

3.手寫函數(shù)柯里化工具函數(shù)、并理解其應(yīng)用場景和優(yōu)勢

理解柯里化:用閉包把參數(shù)保存起來,當(dāng)參數(shù)的數(shù)量足夠執(zhí)行函數(shù)了,就開始執(zhí)行函數(shù)。

// ES6騷寫法
const curry = (fn, arr = []) => (...args) =>
  (arg => (args.length === fn.length ? fn(...args) : curry(fn, arg)))([
    ...arr,
    ...args
  ])

4.手寫防抖和節(jié)流工具函數(shù)、并理解其內(nèi)部原理和應(yīng)用場景

/**
 * description: 防抖
 * param {Function} fn - 定時器每次執(zhí)行調(diào)用的函數(shù)
 * param {Number} [delay = 300] - 定時器執(zhí)行時間間隔
 * author: yanxu gong
 * update: 2019-11-13 9:50
 */
function debounce(fn, delay = 300) {
  let timer = null
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

/**
 * description: 節(jié)流
 * param {Function} fn - 定時器每次執(zhí)行調(diào)用的函數(shù)
 * param {Number} [delay = 500] - 定時器執(zhí)行時間間隔
 * author: yanxu gong
 * update: 2019-11-13 9:50
 */
function throttle(fn, delay = 500) {
  let flag = true
  return (...args) => {
    if (!flag) return
    flag = false
    setTimeout(() => {
      fn.apply(this, args)
      flag = true
    }, delay)
  }
}

5.實現(xiàn)一個 sleep 函數(shù)

Promise 版本

function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time))
}

const t1 = +new Date()
sleep(3000).then(() => {
  const t2 = +new Date()
  console.log('t2 - t1:' + (t2 - t1))
})

優(yōu)點:這種方式實際上是用了 setTimeout,沒有形成進(jìn)程阻塞,不會造成性能和負(fù)載問題。

缺點:雖然不像 callback 套那么多層,但仍不怎么美觀,而且當(dāng)我們需要在某過程中需要停止執(zhí)行(或者在中途返回了錯誤的值),還必須得層層判斷后跳出,非常麻煩,而且這種異步并不是那么徹底,還是看起來別扭

Async/Await 版本

function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time))
}

;(async function() {
  console.log('Do some thing, ' + new Date())
  await sleep(3000)
  console.log('Do other things, ' + new Date())
})()

缺點: ES7 語法存在兼容性問題,有 babel 一切兼容性都不是問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容