/**
* 1、JavaScript的执行机制 eventloop
* 开始执行 => 逐步执行代码 => 有代码异步操作 (异步操作插入队列)=> 执行完毕 => 再次询问是否有异步任务 有的话就再次循环执行上诉操作
* 异步队列里的任务分为两种:
* 1、微任务:Promise,process.nextTick
* 2、宏任务: 整体代码script,setTimeout,setInterval
* 注意:微任务会先于宏任务执行,微任务队列执行完毕后,才会执行下一个宏任务;
* **/

//第一题
setTimeout(()=>{
console.log('set1');
new Promise((resolve)=>{ //同步执行
resolve();
}).then(()=>{ //异步执行
console.log('then4');
})
})
new Promise((resolve)=>{ //同步执行
console.log('pr1');
resolve();
}).then(()=>{ //异步执行
console.log('then1')
})
setTimeout(()=>{
console.log('set2')
})
new Promise((resolve)=>{ //同步执行
resolve();
}).then(()=>{ //异步执行
console.log('then2')
})
console.log(3);
//pr1 3 then1 then2 set1 then4 set2
//微任务:[then1,then2,then4] 宏任务:[set1,set2]

async function a(){ //不算微任务也不算宏任务,本身并不是异步操作,算同步操作,与await配合
var b = await new Promise((resolve)=>{ //await表示等待,如果该promise不返回resolve或者reject则后面的代码不会继续执行,属于异步
resolve(7);
});
console.log(5);
console.log(b);
}
a();
console.log(3);
// 3 5 7


/**
* 2、作用域链与引用类型
* **/
//第二题 闭包
for(var i = 0; i < 10; i++){ //同步代码
setTimeout(()=>{ //异步执行,等到10次for循环完了之后才会执行异步队列,所以会打印出10个10
console.log(i) //10个10
})
//修改为闭包打印出0到9
// (function(i){
// console.log(i) //0-9
// })(i)
}

//第三题
/*var a = [1,2,3];
function f() {
a[3] = 4;
a = [100];
}
f();
console.log(a); //100
*/

/*第四题
var a = [1,2,3];
function f(a) { //a属于形参
a[3] = 4; //局部变量,同时外面的a值也变化了
a = [100]; //这里赋值对外面的全局a不起作用
console.log(a);//函数内部打印a为100
}
f(a);
console.log(a); //1,2,3,4
*/

/**
* 第5题
* var a = {n:1};
var b = a;
a.x = a = {n:2};
console.log(a.x); //undefined
console.log(b.x); // {n:2}
* **/
//js中变量赋值从右向左执行,但是点的优先级最高,所以先是a.x = {n:2},改变了a的内存
// 但是{n:2}又赋值给了a, a此时已经等于{n:2} ,b = a, 相当于b = { n:1, x:{ n:2 }};

/**
* 总结:
* 1、对象、数组是引用类型;
* 2、参数在方法内部,相当于一个局部变量;
* 3、js查找变量会从当前作用域逐级向上查找,直到window,如果没有就为undefined;
* 4、v8引擎里,64位js内存大小是在1.4GB,32位的就是0.7GB, 通过window.p
* 5、js里内存回收 全局变量只有在当前进程结束才会回收,局部变量在失去引用时,且等到进程接近满的时候才会回收,因为回收一次需要把整个进程暂停,这个过程大概需要10秒,会中断js执行;
* 可以手动回收局部变量,将其置为null或undefined
* 6、容易引发内存使用不当的场景:
* a: 滥用全局变量
* b: 缓存不限制
* c: 操作大文件
* **/