2

一、Javascript的执行机制 eventLoop
二、作用域链与引用类型
三、V8引擎内存问题
第一题,输出顺序:
setTimeout(function(){

console.log('set1');

})
new Promise(function(resolve){

console.log('pr1');

resolve()
}).then(function(){

console.log('then1')

})
setTimeout(function(){

console.log('set2');

})
console.log(3);
image.png
*微任务与宏任务-微任务会先于宏任务执行,微任务队列空了,才去执行下一个宏任务。
微任务:Promise,process.nextTick
宏任务:整体代码script(第一次执行的代码),setTimeout,setInterval
第一题进阶:
setTimeout(function(){

console.log('set1');
new Promise(function(resolve)       {
    resolve()
}).then(function(){
    console.log('then4')
})

})
new Promise(function(resolve){

console.log('pr1');

resolve()
}).then(function(){

console.log('then1')

})
setTimeout(function(){

console.log('set2');

})
new Promise(function(resolve){
resolve()
}).then(function(){

console.log('then2')

})
console.log(3);
关于async:
async function a(){console.log('async')}
a();
console.log(3)
//async,3
await实际里面执行是同步的,同步异步主要看里面的内容
改动:
async function a(){

//await从使用上来说,必须等待一个Promise
var b=await new Promise(function(resolve){
    resolve(7)
})
console.log(5);
console.log('b')

}
a();
console.log(3)
// 3,5,7:await等待promise,后面的内容不执行了,除非promise的状态变成resolve或rejece,等待完成才会继续执行。
经典闭包题:
for(var i=0;i<10;i++){

setTimeout(()=>{
    console.log(i)//10...
})

}
for(var i=0;i<10;i++){

(function(i){
    console.log(i)//正确输出
})(i)====>将当前的i缓存到setTimeout的缓存作用域里面去了,拿到的是setTimeout局部的i

}
类似上面的错误:var arr=['url','url','url']
//读数组里面的文件
for(var i=0;i<arr.length;i++){

fs.readFile(arr[i],function(){
    //回调里的操作的文件都是最后一个
})

}

第二题 内存类
var a=[1,2,3];
function f(){a[3]=4;a=[100];} f(); console.log(a);//[100]
function f(a){a[3]=4;a=[100];} f(a); console.log(a);//[1,2,3,4]
js值传递,函数中a的值是a的引用,更改后就不是了。
概念:

**对象,数组是引用类型(赋值指向的是内存地址,不是数据本身)
**参数在方法内,相当于一个局部变量
*js查找变量,从当前作用域逐级向上,直到window,如果window没有,那就是undefined

进阶1*引用类型的深刻历理解--深入内存
var a={n:1};
var b=a;
//a.x .号运算优先级别最高 给a指向的对象{n:1}赋值一个属性x,a.x开辟一块新的内存。此时a和b有x属性。
a.x=a={n:2};// = 运算从右往左。a首先指向{n:2}对应地址,b同。a.x真正赋值a的时候,a已经指向{n:2}这个对象了,里面没有x属性。
console.log(a.x);
console.log(b.x);
// undefine、{n:2}
第三题
*JS内存如何回收
image.png
内存快接近满,---判断1:全局变量--->不回收;---判断2:局部变量且失去引用--->回收;主动赋值null也会释放
PS:js进行一次内存回收会中断js所有执行
*内存查看:1、浏览器-输入window.performance 2、Node调试-process.memoryUsage();
*容易引发内存使用不当的情景:1、滥用全局变量;2、缓存不限制;3、操作大文件;

为什么会内存不足:arrall是全局变量不会被回收
var size=2010241024;
var arrall=[];
//v8 64bit引擎只有1.4g的内存可以支配,node可以使用c++的内存
for(var i=0;i<20;i++){

arrall.push(new Array(size));

}
====>JS stack trace内存不足。
实时查看内存情况:
function getme(){

var mem=process.memoryUsage();
var format=function(bytes){
    return (bytes/1024/1024).toFixed(2)+"MB";
}
console.log('heapTotal:'+format(mem.heapTotal)+'heapUsed:'+format(mem.heapUsed))

}
var size=2010241024;
var arrall=[];
for(var i=0;i<20;i++){

getme();
arrall.push(new Array(size));

}
===>解决:
for(var i=0;i<20;i++){

if(arrall.length>4){
    arrall.shift()//快满的时候删掉
}
getme();
arrall.push(new Array(size));

}


小黄人111
19 声望2 粉丝