vaakian / vaakian.github.io

some notes
https://vaakian.github.io
3 stars 0 forks source link

JavaScript基础or进阶 #16

Open vaakian opened 3 years ago

vaakian commented 3 years ago

2020年面经补基础

vaakian commented 3 years ago

手动实现promise(简单的)

// 手动实现promise
function WPromise(fn) {
  const instance = this
  let status = 'panding'
  let thenFn, catchFn, finallyFn
  this.then = (fn) => {
    console.log('addThen')
    thenFn = fn
    return instance
  }
  this.catch = (fn) => {
    console.log('addCatch')
    catchFn = fn
    return instance
  }
  this.finally = (fn) => {
    console.log('addFinally')
    finallyFn = fn
    return instance
  }
  const resolve = (data) => {
    if (status === 'panding') {
      status = 'resolved'
      console.log('resolved')

      thenFn(data)
      finallyFn()
    }
  }
  const reject = (data) => {
    if (status === 'panding') {
      status = 'rejected'
      console.log('rejected')
      catchFn(data)
      finallyFn()
    }
  }
  // 将fn加入microtask,然后then、finally、catch进入动作
  setTimeout(() => {
    console.log('call fn')
    fn(resolve, reject)
  }, 0)
}

const wp = new WPromise((resolve, reject) => {
  // resolve(500)
  setTimeout(() => {
    reject(Math.floor(Math.random() * 100))
    resolve(Math.floor(Math.random() * 100))
  }, 1500)
})

// 链式调用,作为一次大任务
wp.then((data) => console.log(data))
  .finally(() => console.log('finally'))
  .catch((data) => console.log(data))

// promise中resolve之后的语句也会执行,只会遇到return才会停止
new Promise((resolve) => {
  resolve(500)
  console.log('after resolve')
}).then((data) => console.log(data))
vaakian commented 3 years ago

手动实现apply

const president = {
  firstName: 'Joe',
  lastName: 'Bide',
  fullName(caption) {
    let result = caption + ' ' + this.firstName + ' ' + this.lastName
    return result
  },
}

var person1 = {
  firstName: 'Mary',
  lastName: 'Doe',
}
Function.prototype.myApply = function (obj, args) {
  // 将fn附加到对象上执行,那么他的this就成了该对象了
  obj._fn_ = this
  let retVal = obj._fn_(...args)
  // 运行完记得删除
  delete obj._fn_
  return retVal
}
let president1 = president.fullName.myApply(person1, ['President:'])
let president2 = president.fullName('President:')
console.log(president1)
console.log(president2)
// console.log(person1)
vaakian commented 3 years ago

两种方法实现队列延时执行


new Queue()
  .task(1000, () => console.log(1))
  .task(2000, () => console.log(2))
  .task(3000, () => console.log(3))
  .start()
实现1秒后输出1,然后等待2秒输出2,再等待3秒输出3

代码实现

function Queue() {
  const tasks = []
  let i = 0
  return {
    task(duration, fn) {
      tasks.push({ duration, fn })
      return this
    },
    start() {
      if (i < tasks.length) {
        let currentTask = tasks[i++]
        setTimeout(() => {
          currentTask.fn()
          this.start()
        }, currentTask.duration)
      } else {
        console.log('done!')
        i = 0
      }
    },
    // start() {
    //   const _start = (i) => {
    //     if (i < tasks.length) {
    //       let currentTask = tasks[i]
    //       new Promise((resolve) => {
    //         setTimeout(() => {
    //           currentTask.fn()
    //           resolve(null)
    //         }, currentTask.duration)
    //       }).then(() => _start(i + 1))
    //     }
    //   }
    //   _start(0)
    // },
  }
}
new Queue()
  .task(1000, () => console.log(1))
  .task(2000, () => console.log(2))
  .task(3000, () => console.log(3))
  .start()
vaakian commented 3 years ago

数组扁平化

function flatten(arr) {
  let res = []
  arr.forEach((element) => {
    if (Array.isArray(element)) {
      res = res.concat(element)
      // 数组中可能还有数组
      res = flatten(res)
    } else {
      res.push(element)
    }
  })
  return res
}

console.log(flatten([1, 2, 3, 4, [5, [24, 56], 6]]))

/*
[
  1,  2,  3, 4,
  5, 24, 56, 6
]
*/
vaakian commented 3 years ago

还需加强: BFC eventloop 回流,重绘 节流,防抖 TCP握手

vaakian commented 3 years ago

Vue: 从Object.definePropertyproxy的好处: Proxy不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。