Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一些手写代码 #6

Open
maya1900 opened this issue Mar 23, 2023 · 22 comments
Open

一些手写代码 #6

maya1900 opened this issue Mar 23, 2023 · 22 comments
Assignees
Labels

Comments

@maya1900
Copy link
Owner

maya1900 commented Mar 23, 2023

Object.create:

function create(obj) {
 function F() { }
 F.prototype = obj
 return new F()
}
@maya1900 maya1900 added the js label Mar 23, 2023
@maya1900 maya1900 self-assigned this Mar 23, 2023
@maya1900
Copy link
Owner Author

instance of:

function instanceOf(left, right) {
  let proto = left.__proto__
  let prototype = right.prototype
  while(true) {
    if(!proto) return false
    if(proto === prototype) return true
    proto = proto.__proto__
  }
}

@maya1900
Copy link
Owner Author

function myNew() {
  let context = Array.prototype.shifht.call(arguments)
  const obj = new Object()
  obj.__proto__ = context.prototype
  const result = context.apply(obj, arguments)
  return typeof result === 'object' ? result : obj
}

@maya1900
Copy link
Owner Author

promise.all:

function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    let count = 0
    let res = []
    for (let i = 0; i < promises.length; i++) {
      Promise.resolve(promises[i]).then(val => {
        count++
        res[i] = val
        if (count === promises.length) {
          return resolve(res)
        }
      }, err => {
        return reject(err)
      })
    }
  })
}

@maya1900
Copy link
Owner Author

function PromiseRace(promises) {
  return new Promise((resolve, reject) => {
    for(let i = 0; i < promises.length; i++) {
      promises[i].then(resolve, reject);
    }
  })
}

@maya1900
Copy link
Owner Author

防抖:

function debounce(fn, wait) {
  let timer = null
  return function () {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, arguments)
    }, wait)
  }
}

@maya1900
Copy link
Owner Author

节流:

function throttle(fn, delay) {
  let curTime = Date.now()
  return function () {
    let nowTime = Date.now()
    if(nowTime - curTime > delay) {
      curTime = Date.now()
      return fn.apply(this, arguments)
    }
  }
}

@maya1900
Copy link
Owner Author

Function.prototype.myCall = function (context) {
  let context = context || window
  let args = Array.prototype.slice.call(arguments, 1)
  context.fn = this
  const res = context.fn(...args)
  delete context.fn
  return res
}

@maya1900
Copy link
Owner Author

Function.prototype.myApply = function (context) {
  let context = context || window
  let result = null
  if(arguments[1]) {
    result = context.fn(...arguments[1])
  } else {
    result = context.fn()
  }
  delete context.fn
  return result
}

@maya1900
Copy link
Owner Author

Function.prototype.myBind = function (context) {
  const self = this
  const args = Array.prototype.slice.call(arguments, 1)
  const f = function () { }
  const fb = function () {
    const bindArgs = Array.prototype.slice.call(arguments)
    return self.apply(this instanceof f ? this : context, args.concat(bindArgs))
  }
  f.prototype = this.prototype
  fb.prototype = new f()
  return fb
}

@maya1900
Copy link
Owner Author

柯里化

function curry(fn, ...args) {
  return fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args)
}

@maya1900
Copy link
Owner Author

深拷贝简写:

function deepClone(obj) {
  if(!obj || typeof obj != 'object') return
  const newObj = Array.isArray(obj) ? [] : {}
  for(let key in obj) {
    if(obj.hasOwnProperty(key)) {
      newObj[key] = typeof obj[key] == 'object' ? deepClone(obj[key]) : obj[key]
    }
  }
  return newObj
}

@maya1900
Copy link
Owner Author

数组乱序输出:

var arr = [1,2,3,4,5,6,7,8]
for(var i = 0; i < arr.length; i++) {
  const randomIndex = Math.round(Math.random() * (arr.length - 1 - i)) + i
  const tmp = arr[i]
  arr[i] = arr[randomIndex]
  arr[randomIndex] = tmp
}
console.log(arr)

@maya1900
Copy link
Owner Author

数组扁平化:

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

@maya1900
Copy link
Owner Author

function uniqueArr(arr) {
  return arr.filter((item, index) => arr.indexOf(item) == index)
}

@maya1900
Copy link
Owner Author

数字千分位:

function format(n) {
  const num = n.toString()
  let decimals = ''
  num.indexOf('.') > -1 ? decimals = num.split('.')[1] : decimals
  let len = num.length
  if (len <= 3) {
    return num
  } else {
    let tmp = ''
    let remainder = len % 3
    decimals ? tmp = '.' + decimals : tmp
    if (remainder > 0) {
      return num.slice(0, remainder) + ',' + num.slice(remainder, len).match(/\d{3}/g).join(',') + tmp
    } else {
      return num.slice(0, len).match(/\d{3}/g).join(',') + tmp
    }
  }
}

@maya1900
Copy link
Owner Author

大树相加:

function sumBigNumber(a, b) {
  let res = ''
  let temp = ''
  a = a.split('')
  b = b.split('')
  while (a.length || b.length || temp) {
    temp += ~~a.pop() + ~~b.pop()
    res = (temp % 10) + res
    temp = temp > 9
  }
  return res.replace(/^0+/, '')
}

@maya1900
Copy link
Owner Author

add(1)(2)(3)

function add(m) {
  const fn = function(n) {
    return m + n
  }
  fn.toString = function() {
    return m
  }
  return fn
}

@maya1900
Copy link
Owner Author

json转树结构:

function jsonToTree(data) {
  const res = []
  if(!Array.isArray(data)) {
    return res
  }
  const map = {}
  data.forEach(item => {
    map[item.id] = item
  })
  data.forEach(item => {
    const parent = map[item.id]
    if(parent) {
      (parent.children || (parent.children = [])).push(item)
    } else {
      res.push(item)
    }
  })
  return res
}

@maya1900
Copy link
Owner Author

url params转对象:

function parseParam(url) {
  const paramStr = /.+\?(.+)$/.exec(url)[1]
  const paramArr = paramStr.split('&')
  let paramsObj = {}
  paramArr.forEach(param => {
    if (/=/.test(param)) {
      let [key, val] = param.split('=')
      val = decodeURIComponent(val)
      val = /^\d+$/.test(val) ? parseFloat(val) : val
      if (paramsObj.hasOwnProperty(key)) {
        paramsObj[key] = [].concat(paramsObj[key], val)
      } else {
        paramsObj[key] = val
      }
    } else {
      paramsObj[key] = true
    }
  });
  return paramsObj
}

@maya1900
Copy link
Owner Author

循环打印红绿黄:

function red() {
  console.log('red');
}
function green() {
  console.log('green');
}
function yellow() {
  console.log('yellow');
}
const task = (timer, light) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (light === 'red') {
        red()
      } else if (light === 'green') {
        green()
      } else if (light === 'yellow') {
        yellow()
      }
      resolve()
    }, timer);
  })
}
const step = () => {
  task(3000, 'red').then(() => task(2000, 'green')).then(() => task(1000, 'yellow')).then(step)
}
step()

@maya1900
Copy link
Owner Author

小孩报数问题:

function childNum(num, count) {
  let children = []
  for (let i = 0; i < num; i++) {
    children[i] = i + 1
  }
  let exit = 0
  let counter = 0
  let current = 0
  while (exit < num - 1) {
    if (children[current] != 0) counter++;
    if (counter == count) {
      children[current] = 0
      exit++
      counter = 0
    }
    current++
    if (current === num) {
      current = 0
    }
  }
  for (let i = 0; i < num; i++) {
    if (children[i] !== 0) {
      return children[i]
    }
  }
}
console.log(childNum(30, 3))

@maya1900
Copy link
Owner Author

模拟setTimeInterval:

function mySetTimeInterval(fn, timeout) {
  const timer = {
    flag: true
  }
  function interval() {
    if(timer.flag) {
      fn()
      setTimeout(interval, timeout)
    }
  }
  setTimeout(interval, timeout)
  return timer
}

setInterval 的作用是每隔一段指定时间执行一个函数,但是这个执行不是真的到了时间立即执行,它真正的作用是每隔一段时间将事件加入事件队列中去,只有当当前的执行栈为空的时候,才能去从事件队列中取出事件执行。所以可能会出现这样的情况,就是当前执行栈执行的时间很长,导致事件队列里边积累多个定时器加入的事件,当执行栈结束的时候,这些事件会依次执行,因此就不能到间隔一段时间执行的效果。
针对 setInterval 的这个缺点,我们可以使用 setTimeout 递归调用来模拟 setInterval,这样我们就确保了只有一个事件结束了,我们才会触发下一个定时器事件,这样解决了 setInterval 的问题。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant