预编译
先GO后AO
AO执行顺序先形参定义 变量提升
形参实参统一
函数提升并且定义赋值
闭包
函数内部 return 一个内部函数被外部变量接收
外部变量可以使用内部函数 AO 中的值
闭包的好处是可以防止全局变量污染,但是闭包多了也会有内存泄漏的风险function test1(){function test2(){var b =1console.log(a)
}var a = 3return test2
}var c = 3var test3 = test1()
test3() //3复制代码
答案是 3GO:{c:3test3:functest1:func
}
test1.AO:{a:3test2:func
}
test2.AO:{b:1}
test2.[[scope]] = test2.AO->test1.AO->GO复制代码
tips:闭包里保存的变量有点像 class 里面的类方法(只是形式像其实不一样)function myMath1(num){var num=numfunction myAdd(){return num+1}function myReduce(){return num-1}return [myAdd,myReduce]
}function myMath2(num){var num=num;var options = {add:function myAdd(){return num+1},reduce:function myReduce(){return num-1}
}return options
}var a = myMath1(10)
a[0]() //11a[1]() //10var b = myMath2(10)
b.add() //11b.reduce()//10复制代码
作用域链function a(){function b(){let c = 1}
b()
}
a()复制代码全局生成 GO:{a:func}
a 函数被定义时系统生成
[[scope]]属性,[[scope]]保存该函数的作用域链,该作用域链里的第 0 位存储 GO
a 函数在被执行时(前一刻)进行预编译生成 a 函数的 AO(执行上下文),同时作用域链的第 0 位存储 a 函数的 AO,同时第 1 位存储 GO。查找变量是到 a 函数存储的作用域链中从上往下依次查找。
a 函数预编译时定义 b 函数,生成 b 函数[[scope]]
b 函数被定义时是在 a 函数环境下,所以 b 函数此时的作用域链就是 a 函数被执行时的作用域链
b 函数被执行时(前一刻)进行预编译生成 b 函数的 AO(执行上下文),b 函数 scope 第 0 位存储 b 函数 AO,第 1 位存储 a 函数的 AO,第 2 位存储 Go
b 函数执行完后 b 函数的 AO 被销毁,回归被定义时的状态
a 函数执行完后 a 函数的 AO 被销毁,b 函数的[[scope]]也不复存在,a 函数回归被定义时的状态
tips:上级执行(执行前一刻预编译),下级定义
定义时生成作用域链 scope,执行时(执行前一刻)生成 AO