-
宏微任务 一轮同步代码执行完以后,先把所有微任务一次执行完,再执行下一个宏任务。再把所有微任务一次执行完,再执行下一个宏任务…
代码 类型 普通 JS 代码 同步 Promise 里面的代码 同步 Promise.then()微任务 Promise.catch()微任务 Promise.finally()微任务 async里面await前面 同步 await那一行的代码同步 await后面行的代码微任务 queueMicrotask()微任务 setTimeout()宏任务 setInterval()宏任务 如果一个微任务里面嵌套一个微任务,那么他们都会被同一批执行
const promise = new Promise((resolve, reject) => { console.log(1); console.log(2); }); promise.then(() => { console.log(3); //没有resolve,一直在pending,所以不运行 }); console.log(4); // 124async function async1() { console.log("1"); await async2(); console.log("2"); } async function async2() { console.log("3"); } setTimeout(() => console.log("4"), 0); async1(); new Promise((resolve) => { console.log("5"); resolve(); }).then(() => console.log("6")); console.log("7"); // 1 → 3 → 5 → 7 → 2 → 6 → 4new Promise((resolve) => { console.log(1); resolve(3); Promise.resolve().then(() => { console.log(4); }); }).then((num) => { console.log(num); }); setTimeout(() => { console.log(6); }); Promise.resolve().then(() => { console.log(5); }); console.log(2); // 124356console.log('start'); setTimeout(() => { console.log('Timeout1'); }, 1000); Promise.resolve().then(() => { console.log('Promise1'); }); Promise.resolve().then(() => { console.log('Promise2'); setTimeout(() => { Promise.resolve().then(() => { console.log('Promise3'); }) console.log('Timeout2'); }, 0); }); console.log('end'); // start end Promise1 Promise2 Timeout2 Promise3 Timeout1 同步: start end 第一轮微任务: Promise1 Promise2 宏任务 Timeout2: 先同步输出 Timeout2 并产生微任务 Promise3 然后立刻清空微任务: Promise3 之后: Timeout1 -->function app() { setTimeout(() => { console.log("1-1"); 3; Promise.resolve().then(() => { console.log("2-1"); 4; }); }); console.log("1-2"); 1; Promise.resolve().then(() => { console.log("1-3"); 2; setTimeout(() => { console.log("3-1"); 5; }); }); } -
this 普通函数直接调用:非严格模式 -> window,严格模式 -> undefined
对象调用:看函数名前最后一个点.前面是谁
const f = obj.fn;f();此时this不是obj,而是window或者undefinedcall,bind,apply可以绑定this。只不过bind不会立刻执行该函数。
const newFn = fn.bind(obj); newFn();new使得this指向new出来的新对象
箭头函数没有自己的 this,它不会根据“谁调用它”决定 this。它使用的是外层作用域的 this
const obj = { name: "Navi", fn() { const arrow = () => { console.log(this.name); }; arrow(); }, }; obj.fn(); //fn的this是obj,arrow用的this是fn的this,也就是objvar length = 10; function fn() { console.log(this.length); } var obj = { length: 5, method: function (fn) { //本质上都是在执行同一个 fn 函数 fn(); // 直接调用 arguments[0](); // this = arguments fn.call(obj, 12); // this = obj }, }; obj.method(fn, 1, 2); // undefined 3 5 -
两道题,看看就行。
const n = 10; function print() { console.log(n); } function f1(fn) { const n = 20; fn(); } f1(print); // 10 function fn1() { console.log("fn1"); } var fn2; fn1(); fn2(); fn2 = function () { console.log("fn2"); }; fn2(); // fn1 Uncaught TypeError: fn2 is not a function fn2 -
闭包和循环中的var
function createFunctions() { var funcs = []; for (var i = 0; i < 3; i++) { funcs[i] = function () { console.log(i); }; } return funcs; } var funcs = createFunctions(); funcs[0](); funcs[1](); funcs[2](); //输出为333,如果改成let输出则是012 //换成let会给每一轮循环创建一个新的i,避免闭包 //var:函数作用域 → 多轮循环共享同一个 i //let:块级作用域 + for 的特殊每轮绑定机制 → 每轮循环都有独立的 i -
setTimeout和var在异步操作里面的行为
function test() { for (var i = 0; i < 3; i++) { setTimeout(function () { console.log(i); }, 1000); } } test(); //for 是同步执行的 //setTimeout(...) 本身也同步执行,作用是注册定时器并开始计时。 //但setTimeout 的回调属于宏任务,不能打断当前同步代码。 //当前同步代码执行完后,事件循环会先清空微任务,再执行宏任务。 //var i 是函数作用域,三轮循环共享同一个 i。 //循环结束时 i = 3,所以输出333 可以用let代替varfunction asyncTest() { var result = []; for (var i = 0; i < 3; i++) { setTimeout(function () { result.push(i); }, 1000); } setTimeout(() => console.log(result), 1100); // 延迟打印结果 } asyncTest(); -
this在闭包中
var obj = { count: 0, increment: function () { // 这里 increment 是 obj 调用的 // 所以这里面的 this 指向 obj setTimeout(function () { // 但这个普通函数是 setTimeout 之后单独调用的 // 所以这里的 this 不再是 obj,而是window this.count++; console.log(this.count); }, 1000); }, }; obj.increment(); //得NaN //更改 var obj = { count: 0, increment: function () { setTimeout(() => { // 箭头函数没有自己的 this // 会继承 increment 里的 this,也就是 obj this.count++; console.log(this.count); }, 1000); }, }; obj.increment(); // 1 //或者使用bind increment: function() { // 因为是 obj.increment() // 所以这里 this === obj setTimeout(function() { this.count++; console.log(this.count); }.bind(this), 1000); // 这里的 this 也是 increment 里的 this // 所以相当于 .bind(obj) }
宏微任务
向下滚动可查看阅读进度