JavaScript执行机制——eventloopsetTimeout(function(){console.log('set1');})newPromise(function(resolve){console.log('pr1');//相当于同步代码resolve()}).然后(function(){console.log('then1');})setTimeout(function(){console.log('set2');})newPromise(function(resolve){resolve()}).then(function(){console.log('then2');})console.log(3)//micro['then1','then2'],macro['set1','set2']//pr13then1then2set1set2//加强版setTimeout(function(){console.log('set1');newPromise(function(resolve){resolve()}).then(function(){console.log('then3');})})newPromise(function(resolve){console.log('pr1');//相当于同步代码resolve()}).then(function(){console.log('then1');})setTimeout(function(){console.log('set2');})newPromise(function(resolve){resolve()}).then(function(){console.log('then2');})控制台。log(3)//第一遍micro['then1','then2'],macro['set1','set2']//第二遍,宏任务执行时,微任务会被插入微任务再次排队micro['then3'],macro['set1','set2']//pr13then1then2set1then3set2microtask:Promise,process.nextTickmacrotask:整体代码脚本,setTimeout,setIntervalmicrotask会先于macrotask执行microtask队列为空后才执行下一个macrotaskasyncfunctiona(){console.log('async')}a();console.log(3)//async3asyncfunctiona(){//await在使用上,必须等待一个promisevarb=awaitnewPromise(function(resolve){resolve(7)})console.log(5)console.log(b)}a();console.log(3)//357for(vari=0;i<10;i++){setTimeout(()=>{console.log(i)});}//10次10//闭包解for(vari=0;i<10;i++){(function(i){console.log(i)})(i)}//最好用let组成块级作用域作用域链和引用类型vara=[1,2,3]functionf(){[3]=4;a=[100];}f();console.log(a)//[100]vara=[1,2,3]functionf(a){a[3]=4;a=[100];}f(a);console.log(a)//[1,2,3,4]//解释vara=[1,2,3]functionf(a){vara=a;//有一个隐式代码将外部a赋值给本地aa[3]=4;//因为是引用类型,所以外部a和内部a都变成了[1,2,3,4]a=[100];//给本地a赋值,本地a切断与外部a控制台的连接。log(a)//打印部分a[100]}f(a);console.log(a)//是整个a[1,2,3,4]原则:对象是引用类型leta=[1,2,3];letb=a;//将数组的内存地址指向ba[3]=4;//所有对a和b的修改也会改变,因为内存地址改变了。参数在方法里,相当于想一个局部变量:问题一:js是怎么找变量的?从当前作用域开始,逐级向上查找,直到窗口,如果没有窗口,则为undefinedvarc=123;functiona(){console.log(c);//123}varc=123;函数a(){varc=456;控制台日志(c);//456}问题2:JavaScript数组不是数据结构意义上的数组,为什么?数据结构意义上的数组是一个连续且相等的内存变量。尺寸是在定义的时候指定的。实型数组不能展开。问题三:从数据结构上扩展数组时,内存有什么作用?重新申请一个要扩展的内存,复制扩展前的内容,然后写入要扩展的内容。问题是vara={n:1}varb=a;a.x=a={n:2}console.log(a.x);//undefinedconsole.log(b.x);//{n:2}//解析vara={n:1}varb=a;//a.x.No.优先级最高//a.x会在原内存地址申请新的内存地址a.x=a={n:2}V8引擎内存问题varsize=20*1024*1024;vararrAll=[];for(vari=0;i<20;i++){arrAll.push(newArray(size));}知识点:64位v8引擎只有1.4g内存可供使用,node可以使用增加的内存是C写的,node的源码是c++写的内存是怎么回收的?为什么要等到内存满了再回收呢?因为JavaScript一旦回收就需要暂停整个js,所以不能频繁回收。回收100m内存大约需要10ms。查看浏览器window.performanceNodeprocess.memoryUsage()functiongetMemory(){varmem=process.memoryUsage();varformat=function(bytes){return(bytes/1024/1024).toFixed(2)+"MB";}console.log('heapTotal'+format(mem.heapTotal)+'heapUsed:'+format(mem.heapUsed));}varsize=20*1024*1024;vararrAll=[];for(vari=0;我<20;我++){getMemory();arrAll.push(newArray(size));}如何解决?如果不确定自己的数据是否太大放不下全局,可以做一些大小限制varsize=20*1024*1024;vararrAll=[];对于(vari=0;i<20;i++){if(arrAll.length>4){arrAll.转移();}全部。推(新数组(大小));getMemory();}从上图可以看出,数据虽然被限制删除了,但是仍然在内存中,没有被回收。直到内存快满了才回收,无用的回收当内存掉线时,内存恢复到真正可用的状态。总结:使用node写服务时,只要服务开启,全局不会被回收,容易导致内存使用不当。滥用全局变量缓存不限制大文件的操作。
