04 | 函数表达式:涉及大量概念,函数表达式到底该怎么学?
该思维导图由 AI 生成,仅供参考
函数声明与函数表达式的差异
- 深入了解
- 翻译
- 解释
- 总结
JavaScript中的函数表达式是一项基础且重要的概念,它可以用于实现代码隐藏和变量隔离。本文通过比较函数声明和函数表达式的差异,深入探讨了V8引擎处理函数声明的过程。在V8执行JavaScript代码时,会先对其进行编译,然后再执行。在编译阶段,V8会将函数声明转换为内存中的函数对象,并将其放到作用域中,这一过程称为变量提升。相比之下,函数表达式具有不同的语义和行为。函数表达式在编译阶段并不会将函数对象提升到全局作用域中,因此无法在函数表达式之前使用该函数。此外,文章还介绍了立即调用的函数表达式(IIFE)的概念和应用。通过本文的解析,读者可以更深入地理解函数表达式的底层工作机制,从而更好地应用于实际项目中。文章还留下了一道经典面试题,引发读者思考和讨论。 总的来说,本文通过深入解析V8引擎处理函数表达式的过程,帮助读者更好地理解了函数声明和函数表达式之间的区别,以及立即调用的函数表达式的应用。文章内容丰富,涵盖了函数表达式的底层工作机制和实际应用,适合对JavaScript感兴趣的读者阅读学习。
《图解 Google V8》,新⼈⾸单¥59
全部留言(38)
- 最新
- 精选
- 白闹老师,我有一个巨大的疑问,麻烦您有时间的话,一定帮我解答,回答是或不是就行! 在函数即对象一文,您提到“函数有个隐藏属性是 code 属性,其值表示函数代码,以字符串的形式存储在内存中。”,所以我理解成了,函数本质是储存在栈中的! 可是在这篇文里,你明确说到函数是被v8储存在堆中里的。 能解释下,具体是什么回事么? 因为感觉函数和普通对象还是有些区别的,之前看那篇文章里提到的code属性,以为区别就是函数有一部分是储存在栈中,现在似乎是我理解错了?请帮忙确认一下,谢谢老师!!
作者回复: 抱歉,最近事情一堆,忙得不可开交,耽误回复问题了! 不知道我理解你的意思对不对,你的意思是无论什么原生类型都是存放在栈中的,比如某个对象中的一个属性值,如果它是个原生类型,那么原生该值会存放在栈中! 这个理解是错误的,如果你定义了一个对象,那么在运行时,改对象一定是存放在堆中的,包括对象里面的原生类型的属性值也是存放在堆中的! 所以当一个V8在编译阶段解析到一个函数声明时,它首先在堆中创建改函数对象,然后为改对象设置各个属性值! 还有问题欢迎继续提问🤗
2020-04-1025 - 奕在文中一会说 解析阶段,一会说编译阶段,这里这两个概念是一样的吧,解析阶段就是编制阶段,生成 作用域和字节码
作者回复: 嗯 , 大的范围上来讲,我把从源码解析到输出字节码和字节码编译为二进制代码,都称为编译阶段,执行字节码和执行二进制代码称为执行阶段! 小范围来讲,编译阶段又分为解析,预解析、生成字节码、编译成二进制代码! 这里一个是大范围的编译,一个是小范围的! 写的时候也注意到这个问题了,但是没有想到一个更简洁的方式
2020-03-24218 - Corryenjoy有一个疑问,以前看过一个篇阮一峰老师的关于loop event的文章。里面有一句话是这样的:“所有任务都在主线程上执行,形成一个执行栈。“ 按照当前文章的理解,所有的程序在执行前引擎都会有一个编译过程,生产作用域和字节码。这样在编译过程中,函数的执行应该会把所有的函数加入一个执行队列中,然后按照先进先出方式对函数进行执行。这样的理解对于在主线程的任务应该是一个执行队列,而不是一个执行栈。 所以想请老师帮忙解惑一下~
作者回复: 消息队列里面的存放的是一个个嗷嗷待执行的任务,然后主线程会从消息队列中按照特定的策略: while(1){ 取出任务() 执行任务() } 在执行每个任务的过程中,都会有一个栈结构来管理这个任务的函数调用关系; 所以说,执行栈又称调用栈,它是针对消息队列中的单个任务的!
2020-04-0814 - 王楚然思考题: 1. 输出100,100。函数表达式立即执行,修改n值为100。 2.输出1,100。 函数只是被放入作用域,并未执行,因此n值先为1,调用函数后为100。
作者回复: 没问题
2020-03-24210 - qinsi文中提到IIFE的写法是 (function () { //statements })() 而第一题里是 (function () { //statements }()) 效果是一样的
作者回复: 是的
2020-03-2426 - 一飞同学从 V8 编译的角度理解变量提升,豁然开朗,比之前的理解清晰多了。
作者回复: 赞
2020-04-092 - 洋洋第一题输出: 100 100 第二题输出: 1 100
作者回复: 没问题
2020-03-242 - 杨越老师,函数立即表达式是一种特别的表达式,主要用来封装一些变量、函数,可以起到变量隔离和代码隐藏的作用。难道函数声明就不能封装变量和函数从而起到变量隔离和代码隐藏的作用了吗???再者,代码隐藏作何解???还望老师百忙中回复这两个问题
作者回复: 因为当初JavaScript只有函数级作用域,没有块级作用域和空间作用域,所以要实现模块化开发,隐藏内部函数和变量只能使用函数,通常情况下,我们使用函数立即表达式,也就是将一个函数内部需要使用的方法和变量直接暴露给一个全局变量! 函数和函数立即表达式都能隐藏变量,但是通常模块化开发都是使用函数立即表达式来封装内部方法和变量,并直接返回需要暴露的内容!
2020-03-2421 - 流乔老师说的编译一个版本的D8工具啥时候放出来呀?期待。辛苦老师😉😉😉
作者回复: 下周
2020-03-241 - 淡我想问下,文章在讲变量声明以及函数声明提升可以解释一些现象,其他脚本语言很少见到变量和函数提升,JS中它出现的背景是什么?是JS标准就这么规定死的?
作者回复: 主要是JS当初的定位是一个非常简单的脚本语言,并没有想搞得太复杂了,不支持块级作用域,所以就搞了个变量提升的坑! 一直祸害至今,虽然目前已经支持块级别了作用域了,但是还要同时支持变量提升这个坑
2020-03-2421