为何console.log无需加括号也能输出?求原理详解
代码执行机制解析
核心知识点:函数作为回调的传递逻辑
- 当API(比如Promise的
.then())需要接收回调函数时,你可以直接传递函数本身(比如console.log),不用加括号。加括号意味着立即执行函数并传递返回值,不加括号是传递函数引用,让API在合适时机自动调用它。 console.log本身是函数,当它被作为.then()的回调时,Promise会自动把resolve的值作为参数传给它,效果等价于写then(value => console.log(value))。
逐行拆解代码执行流程
new Promise((resolve)=> resolve(5)) .then(data=> console.log(data)) .then(Promise.resolve(10).then(console.log));
同步创建第一个Promise
new Promise((resolve)=> resolve(5))的执行器函数是同步运行的,直接调用resolve(5),这个Promise立即变为fulfilled状态,值为5。绑定第一个
.then()回调.then(data=> console.log(data))把箭头函数加入微任务队列,等待当前所有同步任务完成后执行。同步计算第二个
.then()的参数
这里的参数是表达式Promise.resolve(10).then(console.log),会同步完成求值:Promise.resolve(10)同步创建一个fulfilled状态的Promise,值为10。- 调用它的
.then(console.log):把console.log作为回调传入,因为原Promise已处于fulfilled状态,这个回调被加入微任务队列。 - 这个
.then()最终返回一个新的Promise(状态会在console.log(10)执行后变为fulfilled,值为undefined),该Promise对象会被当作第二个.then()的参数。
同步任务结束,处理微任务队列
- 先执行第一个微任务:第一个
.then()的箭头函数,接收值5并调用console.log(5),输出5。执行完成后,第一个.then()返回的Promise变为fulfilled,值为undefined。 - 再执行第二个微任务:
Promise.resolve(10).then(console.log)的回调,接收值10并调用console.log(10),输出10。 - 最后,第二个
.then()接收到的是之前返回的Promise对象,但.then()要求参数为函数,传入非函数会触发值穿透(等价于.then(v => v)),这个回调不会产生额外输出。
- 先执行第一个微任务:第一个
输出顺序说明
微任务队列遵循先进先出原则,第一个.then()的回调先被加入队列,因此先输出5,再输出10。
内容的提问来源于stack exchange,提问作者akhtarvahid
相关产品推荐
相关产品推荐

