作者回复: 关于foo函数执行上下文销毁过程:foo函数执行结束之后,当前执行状态的指针下移到栈中的全局执行上下文的位置,foo函数的执行上下文的那块数据就挪出来,这也就是foo函数执行上下文的销毁过程,这个文中有提到,你可以参考“调用栈中切换执行上下文状态“图。
第二个问题:innerBar返回后,含有setName和getName对象,这两个对象里面包含了堆中的closure(foo)的引用。虽然foo执行上下文销毁了,foo函数中的对closure(foo)的引用也断开了,但是setName和getName里面又重新建立起来了对closure(foo)引用。
你可以:
1:打开“开发者工具”
2:在控制台执行上述代码
3:然后选择“Memory”标签,点击"take snapshot" 获取V8的堆内存快照。
4:然后“command+f"(mac) 或者 "ctrl+f"(win),搜索“setName”,然后你就会发现setName对象下面包含了 raw_outer_scope_info_or_feedback_metadata,对闭包的引用数据就在这里面。
作者回复: 挺好 继续
作者回复: 函数就是一种特别的对象,所以会保存在堆上,编译函数时,这个函数的已经存在于堆中了!
第二个问题返回了c对象的话,那么说明全局环境对c对象有引用,既然有引用那么就不会被垃圾回收器标记出来,所以c对象也就不会回收!
作者回复: macos的keynote
作者回复: 看来我有必要重新解释一下静态类型和动态类型,强类型和弱类型的区别了!
要理解一门语言是静态类型还是动态类型,最本质的判断方法是看在什么时间段对类型就行检测,静态类型的语言会在编译阶段就行检测,动态类型的语言会在运行时做类型检测!
比如C/C++是静态语言,会在编译阶段对类型就行检测,如果检测到不合法的语言,编译阶段就会报错!
而JavaScript就是动态语言,编译阶段不会做太多类型检测,而是等到运行时再检测变量的具体类型,这是动态语言性能低于静态语言的一个关键的地方。V8对这种动态性做了大量的优化!
要理解一门语言是弱类型还是强类型,看变量在运行时,是否能够改变类型,比如C/c++/javaScript,都可以在运行时将一种类型的变量,改成另外一种类型的,所以他们是弱类型,而JAVA就不能运行过程中修改变量类型,所以是静态语言!
你再结合这两点看文中的内容!
作者回复: 其实闭包对象就是对词法作用域的一种实现
作者回复: 多谢哈,在准备V8的课程了