文章目录
一、栈
1.定义
栈:一种受限制的线性表,遵循后近先出(Last In First Out)
2.实现
class Stack {
constructor() {
this.items = []
}
// 选择一个元素到栈顶
push(ele) {
this.items.push(ele)
}
// 出栈
pop() {
this.items.pop()
}
// 返回栈顶元素
peek() {
return this.items[this.items.length - 1]
}
// 判断是否为空栈
isEmpty() {
return this.items.length === 0
}
// 获取栈中元素的个数
size() {
return this.items.length
}
// 清空栈
clear() {
// this.items.length = 0
// this.items = []
this.items.splice(0, this.items.length)
}
}
const stack = new Stack()
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
console.log(stack)
console.log(stack.peek())
console.log(stack.isEmpty())
stack.pop()
console.log(stack)
stack.clear()
console.log(stack)
3.扩展
(1)清空数组的三种方法
1.a.length = 0
2.a = []
3.a.splice(0,a.length)
4.栈的应用
(1)十进制转二进制
// 十进制转二进制
const binary = number => {
let stack = new Stack()
let remainder = 0
let top = ''
while (number > 0) {
// 除以二,取余数
remainder = number % 2
stack.push(remainder)
// 向下取整
number = Math.floor(number / 2)
}
// 不为空的时候
while (!stack.isEmpty()) {
// 取栈顶
top += stack.pop()
}
return top
}
console.log(binary(100)) //1100100
二、队列
1.定义
队列:一种受限制的线性表,遵循先近先出(First In First Out)
2.实现
class Queue {
constructor() {
this.items = []
}
// 入队
enqueue(ele) {
this.items.push(ele)
}
// 出队
dequeue() {
this.items.shift()
}
// 查看队首元素
front() {
return this.items[0]
}
// 查看队尾元素
real() {
return this.items[this.items.length - 1]
}
// 查看队列是否为空
isEmpty() {
return this.items.length === 0
}
// 长度
size() {
return this.items.length
}
// 清空
clear() {
this.items = []
}
}
三、异步线程与同步线程
1.原理
- JS时单线程语言,浏览器只会分配一个主线程给JS,用来执行任务(函数),一次只能执行一个任务。
- 主线程里维护着一个“任务队列”,这个任务保存着异步的代码。
- 所有代码都在主线程执行,形成一个执行线。
- 只要有了异步代码,就会在“任务队列”里面放置一个事件。
- 一旦执行线所有的同步任务执行完毕以后,系统就会去读取“任务队列”,将对应的异步任务放入执行线,执行异步任务。
主线程不断重复以上步骤
事件循环(Event Loop):主线程执行完毕以后,从事件队列中读取任务队列的过程。
例子:
console.log(1)
setTimeout(() => {
console.log(2)
}, 50)
setTimeout(() => {
console.log(3)
}, 0)
console.log(4)
// 结果:1 4 3 2
2.异步代码:定时器、ajax、事件
3.执行顺序:
- 最先执行的是:同步代码,执行完毕后立即出栈,让出主线程,此时主线程处理空闲状态
- 主线程读取任务列表为队列,触发条件相同时,遵循先进先出;触发条件不同时,执行先到达触发条件的代码。
- 定时器的时间为0秒代表同步代码一执行完毕,就立即执行该定时器的内容。
四、宏任务队列,微任务队列
/**
* 1.同步代码
* 2.new Promise 的时候,excutor函数是立即执行的,说明Promise本来就是同步的
* 3.基于then或者catch存放的方法是异步的
*/
new Promise((resolve, reject) => {
// excutor
console.log(1)
resolve()
}).then(() => {
console.log(2)
})
console.log(3)
// 1 3 2
任务队列:存在两个队列,一个是宏任务队列,一个是微任务队列
主线程:同步任务>微任务>宏任务
宏任务队列:I/O、定时器、事件绑定、ajax…
微任务队列:Promise.then catch finally、process.nextTick、async、await