这一集讲了:函数执行过程原理,作用域链原理
提升作用域应该了解了,变量名提升上去但是不赋值,执行时候才赋值,但是函数就不一样,到了函数这里按道理应该是,foo: undefined,这样,但是他会把这个函数放在内存中,然后把undefined替换成内存地址
如果这个函数里还有函数,那就先预编译(❓疑问不太明白预编译具体是什么样),到了这个外层函数执行的时候,再去编译这样子。
然后函数开始执行(栈底那个foo)找foo这个函数,顺着VO => GO,找到内存地址,然后创建一个 函数执行上下文FEC(我觉得是创建这一步就编译内嵌的函数吧),里面还有个VO,不再指向GO了,而是新建一个AO动态对象,还有scope作用域加上父级作用域,然后在这里面开始执行函数里面的代码,顺着作用域链去找变量。 调用内嵌函数的时候,顺着找到内存地址,然后创建函数执行上下文,套娃吗,再来一遍刚才的操作,函数执行完后,函数执行上下文就会出栈(扔掉),对应的AO没有引用指向它了也会被销毁,还有保存的函数体那个也会销毁,但是要是写的是闭包,还有别的引用引向它,就不会销毁(还没讲到)。
函数执行上下文里的VO和作用域链那一块,其实还有个东西:this,不过是在运行的时候进行绑定,然后还有个东西:arguments
函数调用函数
一道题,下面的输出结果是什么
var message = 'hello Global'
function foo () {
console.log(message)
}
function bar () {
var message = 'hello bar'
foo()
}
bar()
结果是:hello Global,因为bar里的message是在bar里面定义的,和外面的没有关系,所以foo函数打印的message是foo的上一层全局对象的message。
老师推荐书籍:强烈推荐红宝书,和你不知道的JavaScript(在语言设计层面讲的深)
闭包定义

休息一下
上面讲的都是老版本的东西了,es5之前的。 关于VO,有了变化:VO从对象变成了Variable Environment(变量环境);之前是把变量和函数的参数作为属性添加到VO,现在是绑定到变量环境作为环境记录
这时候不一定是对象了,可以用map等等自由选择❓疑问这样会有什么区别吗
2点了02:04, 看到了2h处,还有1h,留给明天看吧。
用node来跑代码比较快,直接在vscode里打开终端看结果,比拉到html再打开浏览器方便多了。(不过要调试的话估计还得去浏览器里🤔)
[[2022-08-04]]继续继续
function foo() { //这里的a变量会写进AO吗? 答案:会
console.log(a)
return //这里return不管他,执行函数阶段才看这个
var a = 100 //所以仍然会把这个a提出到AO动态对象并定义undefined,正常流程
}
不写var就变成全局变量-的原因
function foo () {
m = 100
}
foo()
console.log(m) //100
这种情况,因为没有用var之类的声明,就不会把m放进AO里,执行的时候就顺着去上一级(这里也就是GO)去找,也找不到,就到最头GO里面定义一下m(我的理解)
关于 var a = b = 10
var a = b = 10
//相当于👇
var a = 10
b = 10 //全局了这个
顺序是,10赋值给b,b赋值给a
内存管理
有些编程语言需要我们手动管理内存,有的语言自动帮我们管理内存
内存管理的生命周期
- 分配申请需要的内存
- 使用分配的内存,存东西,对象等
- 不需要时,释放
手动管理内存:c、c++,OC-早期ios的 自动管理:java、JavaScript、python、Swift、Dart
内存分配方式 -JavaScript
基本数据类型 - 直接在栈空间进行分配 复杂数据类型 - 堆内存中开辟一块空间,将这块空间的指针返回值变量引用
这跟线,就是引用的意思,(在c语言里就是指针)
js的垃圾回收机制-GC(Garbage Collection)
用js的时候,申请内存可以不用管,释放内存的时候 一般 也是不用管,闭包的时候要管,会有内存泄漏(内存泄漏是啥)
什么是垃圾?那些不再使用的对象
GC怎么知道哪些对象是垃圾呢?
垃圾回收器的算法-GC算法
有两个算法:
- 引用计数:
想到了在VS里写c#时候看见每个函数上面都会写 0个引用 1个引用的。
弊端: ab之间互相引用,就是无限循环了
2.标记清除 设置一个根对象root object(在这里就是GO),GC就会定期从这个根对象开始找,找所有从根对象开始引用到的对象,没有引用到的就认为是不可用对象(不可达对象)
标记的是可以达到的对象,不可达对象到时候就要被清除了
js采用的是标记清除 (当然V8引擎里更复杂一点,用到了其他的算法,对不同的对象采用不同的算法,让效率更高)
内存泄漏:该释放的对象没有被释放掉(??这就是泄漏吗)