JS堆、栈、执行栈和EventLoop
堆、栈
引用类型在栈中保存指针,在堆中保存对象值
执行栈
JS 代码在运行前都会创建执行上下文,也可以理解为执行环境,JS 中有三种执行上下文:
全局执行上下文,默认的,在浏览器中是 window 对象
函数执行上下文,JS 的函数每当被调用时会创建一个上下文。
Eval 执行上下文,eval 函数会产生自己的上下文。栈,是一种数据结构,遵循先进后出的原则。JS 中的执行栈就具有这样的结构,当引擎第一次遇到 JS 代码时,会产生一个全局执行上下文并压入执行栈,每遇到一个函数调用,就会往栈中压入一个新的上下文。引擎执行栈顶的函数,执行完毕,弹出当前执行上下文。
function foo(){
console.log(1);
bar();
console.log(3);
}
function bar(){
console.log(2);
}
foo();
首先执行这个JS文件,创建一个全局上下文,并压入执行栈中,当 foo() 函数被调用时,将 foo 函数的执行上下文压入执行栈,接着执行输出 ‘1’;当 bar() 函数被调用,将 bar 函数的执行上下文压入执行栈,接着执行输出 ‘2’;bar() 执行完毕,被弹出执行栈,foo() 函数接着执行,输出 ‘3’;foo() 函数执行完毕,被弹出执行栈,最后清空整个执行栈。这就是先进后出,Foo先被压入执行栈,最后才被弹出执行栈
所有JS代码运行,都需要放入执行栈中.
执行上下文包含了三种(全局、函数、eval)
栈是一种数据结构,遵循先进后出
console.log(1);
new Promise(function(resolve){
console.log(3);
resolve(100);
}).then(function(data){
console.log(data);
})
setTimeout(function(){
console.log(4);
})
console.log(2);
1、创建全局上下文,并压入执行栈中
2、把同步代码console.log压入执行栈中执行,打印1,并出栈
3、把同步代码new Promise压入执行栈中执行,打印3,并出栈
这里为什么同步代码,一个进栈一个出栈,而不是遵循先进后出的原则????而函数嵌套会有压栈,先进后出???
浏览器的JS中,异步任务又分为宏任务和微任务,宏任务和微任务都是属于队列,而不是放在栈中。微任务会创建一个队列,宏任务会创建一个队列,而主线程执行完以后,会优先执行微任务,把微任务全部放到执行栈中执行,最后再从宏任务中取出一个放入执行栈进行执行,执行完后,再取一个,直到执行完所有的宏任务。
总结:
JavaScript具备自动垃圾回收机制
JS内存分为堆内存和栈内存
引用类型在栈中保存指针,在堆中保存对象值
所有JS代码运行,都需要放入执行栈中.
执行代码前,会先创建执行上下文
执行上下文包含了三种(全局、函数、eval)
同步任务先执行,异步任务放队列
微任务先执行,宏任务后执行
微任务全部拉入执行栈,宏任务一次拉一个
栈是先进后出,队列是先进先出
此文章为学习摘录记录,并非原创,具体参考文章 https://blog.csdn.net/weixin_39847722/article/details/111261999