Que sera, sera
花里胡哨的欢迎页面
// 浏览器事件循环
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
}
}