OYRC

Que sera, sera

一些题目

-OY欧阳

标签: JavaScript,文章,笔记


          

// 浏览器事件循环
async function a1() {
  console.log('a1 start') // 2
  await a2()
  console.log('a1 end') // 微任务 稍等2 7
}
async function a2() {
  console.log('a2') // 3
}
console.log('script start') // 1
setTimeout(() => {
  console.log('setTimeout') // 宏任务 等会儿 微任务也搞完了 10
}, 0)
Promise.resolve().then(() => {
  console.log('promise1') // 微任务 稍等1 栈里的搞完了开始执行微任务了 6
})
a1()
let promise2 = new Promise((resolve) => {
  resolve('promise2.then') // xx任务 反正等一下 它这是返回给then的结果所以
  console.log('promise2') // 4
})
promise2.then((res) => { // .then都是微任务 稍等
  console.log(res) // 微任务,这个res是上面resolve('promise2.then') 给过来的 8
  Promise.resolve().then(() => {
    console.log('promise3') // 微任务呀 9
  })
})
console.log('script end') // 5

// safari 的微任务推出好像顺序有点不同,

// script start
// a1 start
// a2
// promise2
// script end
// promise1
// a1 end
// promise2.then
// promise3
// setTimeout



// node 的事件循环
/**
 * nodejs的事件循环简化为三个部分,这三个部分必须按顺序执行
 * timer:setTimeout,setInterval放在这里执行
 * 
 * poll:在这里等待时间的流逝,这个阶段的时长最长,所以大部分概率是从这个点开始执行
 * 
 * check:setImmediate放在这里执行
 * 
 */








// 实现bind  简单版 不支持new
function bind1(asThis, ...args) {
  const fn = this
  return function (...args2) {
    return fn.call(asThis, ...args, ...args2)
  }
}
// 实现bind 正经版本  不支持new
var slice = Array.prototype.slice
function bind2(asThis) {
  var fn = this
  var args = slice.call(arguments, 1)
  if (typeof fn !== 'function') {
    throw new Error('bind 必须调用在函数身上')
  }
  function resultFn() {
    var args2 = slice.call(arguments, 0)
    return fn.apply(
      resultFn.prototype.isPrototypeOf(this) ? this :
        asThis, args.concat(args2))
  }
  resultFn.prototype = fn.prototype
  return resultFn
}

// 实现bind es6完整版本  支持new
function bind3(asThis, ...args) {
  const fn = this
  function resultFn(...args2) {
    return fn.call(
      this instanceof resultFn ?
        this : asThis,
      ...args, ...args2)
  }
  resultFn.prototype = fn.prototype
  return resultFn
}



//  实现一个new操作
function _new(func) {
  var res = {};
  if (func.prototype !== null) {
    res.__proto__ = func.prototype;
  }
  var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
  if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
    return ret;
  }
  return res;
}





// 二分查找
// 二分查找是需要一个有序序列,所以这里默认传递进来的是有序数组
const search = (arr, tag) => {
  let low = 0
  let high = arr.length - 1
  let mid
  while (low <= high) {
    mid = parseInt((low + high) / 2)
    if (tag === arr[mid]) {
      return mid
    } else if (tag < arr[mid]) {
      high = mid - 1
    } else if (tag > arr[mid]) {
      low = mid + 1
    } else {
      return -1
    }
  }
  return mid
}


// js 深拷贝
class DeepClone {
  constructor() {
    this.cache = []
  }
  clone(source) {
    if (source instanceof Object) {
      let cacheDist = this.findCache(source)
      if (cacheDist) {
        return cacheDist
      } else {
        let dist
        if (source instanceof Array) {
          dist = new Array()
        }
        else if (source instanceof Function) {
          dist = function () {
            return source.apply(this, arguments)
          }
          //  dist = source.bind(this, ...arguments)
        }
        else if (source instanceof RegExp) {
          dist = new RegExp(source.source, source.flags)
        }
        else if (source instanceof Date) {
          dist = new Date(source)
        }
        else {
          dist = new Object()
        }
        this.cache.push([source, dist])
        for (const key in source) {
          // for in 默认会遍历原型上的属性,所以需要加上
          if (source.hasOwnProperty(key)) {
            dist[key] = this.clone(source[key])
          }
        }
        return dist
      }
    }
    return source
  }
  findCache(source) {
    for (let i = 0; i < this.cache.length; i++) {
      if (this.cache[i][0] === source) {
        return this.cache[i][1]
      }
    }
    return undefined
  }
}

// 去除前后空格
str.replace(/(^\s)|(\s$)/g, '')


// 二叉树
let tree = {
  rt: 1,
  l: {
    rt: 2,
    l: {
      rt: 4,
      l: {
        rt: 7,
      },
      r: {
        rt: 8
      }
    },
    r: {
      rt: 5,
      r: {
        rt: 9,
        l: {
          rt: 12,
        }
      }
    }
  },
  r: {
    rt: 3,
    r: {
      rt: 6,
      l: {
        rt: 10
      },
      r: {
        rt: 11
      }
    }
  }
}
const treeOderF = (tree = {}) => {
  if (tree.rt) {
    console.log(tree.rt)
    treeOderF(tree.l)
    treeOderF(tree.r)
  }
}

const treeOderM = (tree = {}) => {
  if (tree.rt) {
    treeOderM(tree.l)
    console.log(tree.rt)
    treeOderM(tree.r)
  }
}

const treeOderB = (tree = {}) => {
  if (tree.rt) {
    treeOderM(tree.l)
    treeOderM(tree.r)
    console.log(tree.rt)
  }
}



// 事件循环
/**
 * 宏任务 ----- macrotasks -----  一会儿
 * setTimeout
 * I/O
 * UI渲染
 * 
 * 微任务 ----- microtasks ----- 马上
 * promise
 */

async function async1() {
  console.log('async1 start');// 2
  await async2();
  console.log('async1 end'); // 微任务 稍等1 6
}
async function async2() {
  console.log('async2');// 3
}
console.log('script start'); // 1
setTimeout(function () {
  console.log('setTimeout'); // 宏任务 等会儿 8
}, 0)
async1();
new Promise(function (resolve) {
  console.log('promise1');// 4 这个是立即执行的
  resolve();
}).then(function () {
  console.log('promise2'); // 微任务 稍等2 7
});
console.log('script end'); // 5 可以开始刚刚没做的了

// script start 
// async1 start 
// async2
// promise1
// script end
// async1 end // 在safari 中,这两个顺序换了过来
// promise2   // 在safari 中,这两个顺序换了过来
// setTimeout




// 带缓存的斐波那契函数
// ---------1-------------
f = (n) =>
  n === 0 ? 0
    : n === 1 ? 1
      : f(n - 1) + f(n - 2)

// 尾递归优化 斐波那契
f = (n) => f_inner(2, n, 1, 0)
f_inner = (start, end, prev1, prev2) =>
  start === end ? prev1 + prev2
    : f_inner(start + 1, end, prev1 + prev2, prev1)

// 有一个字符串str,完全由(){}[]这些字符组成,返回是否是正确匹配的括号
const isM = (str = '') => {
  let strA = [...str]
  let h = []
  let l
  strA.forEach(e => {
    l = h[h.length - 1]
    switch (e) {
      case '(':
        h.push(e)
        break;
      case ')':
        if (l === '(') {
          h.pop()
        }
        break;
      case '[':
        h.push(e)
        break;
      case ']':
        if (l === '[') {
          h.pop()
        }
        break;
      case '{':
        h.push(e)
        break;
      case '}':
        if (l === '{') {
          h.pop()
        }
        break;
    }
  })
  if (h.length) {
    return false
  } else {
    return true
  }
}






          
CLOSE