• 堆是指一块已分配的用来存储所需数据的存储空间(内存)。
    
    对象的值被分配在一个堆中,并用一个地址记录该值存储的位置,
    这个地址存储在命名对象的变量(内存,也可以说栈内存)中。
    所以复制这个变量只是复制了引用地址,而不是复制了这个对象。
    
  • 栈 (先进后出)
    栈可以看作一个按照顺序排列的消息数据(事件)集合。
    
    这个集合可以看作是一个内部嵌套了一个方法的函数,
    而这个内部方法又嵌套了一个方法,就这么嵌套了N层。
    当执行这个方法时,需要先执行内部的方法,也就是要先执行最内部的方法,然后就是等内部的一层层方法按照嵌套层级的反向顺序执行完毕,才能执行最外层的方法。
    
    所以当你执行这么一个方法(栈)时,就是要先执行“最后来的方法”,所以叫做先进后出。
    
    
    JavaScript是单线程语言,主线程执行同步代码。
    函数调用时, 便会在内存中形成了一个“调用记录”, 又称“调用帧”, 保存调用位置和内部变量等信息。 如果函数内部还调用了其他函数,那么在调用记录上方又会形成一个调用记录, 
    所有的调用记录就形成一个“调用栈”。(闭包、尾调用、尾递归优化)
  • 队列 (先进先出)
    队列也可以看作是指一个按照顺序排列的消息事件集合。
    
    区别就是队列像一个直线单向传送带,先传送到终点的物品,先进行处理。
  • 总结与拓展
    javaScript是单线程的,不能同时执行多个任务,单线程就意味着所有任务需要排队。
    但是在javaScript里面,很多时候阻止线程运行的很慢的是网络IO之类;
    这时候CPU是空闲的,这样就会造成资源的浪费,所以javaScript在主线程之外实现了一个任务队列,
    像IO之类比较慢的操作暂时都会挂在任务队列上,这样不会影响到主线程上任务的执行,
    等到IO的响应回来后再回到主线程上来执行挂起的任务。
    比如Ajax请求、定时器等、UI事件等都会先进入到任务队列上,而不是挂在主线程上。 
    任务队列里的每个任务都可以看作是一个由多个事件组成的(任务)栈,所以这个任务队列就可以看作一个由多个(任务)栈组成的队列,
    当这个队列中的某一个(任务)栈执行完毕(清空)以后,就会把这个(任务)栈移除,然后在主线程上面执行该(任务)栈返回的最终消息。 这个处理过程包含了调用与这个消息相关联的函数(以及因而创建的一系列初始堆栈帧)。 当栈为空的时候,也就意味着消息处理结束。 这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。
    JS是单线程, 主线程执行同步代码, 事件、I/O操作等异步任务,将会进入任务队列执行,异步执行有结果之后,就会变为等待状态, 形成一个事件,
    主线程的同步代码执行完之后,再从”任务队列”中读取事件, 执行事件异步任务的回调。 这就是为什么执行顺序是, 同步 > 异步 > 回调
    更简单的说:只要主线程空了(同步),就会去读取”任务队列”(异步),这就是JavaScript的运行机制。
01-16 10:43