执行上下文
不得不提啊
执行上下文是为了提供各种数据的(包括变量和函数)
每一段代码在调用时,都会产生一个执行上下文。
执行函数代码会产生一个函数执行上下文,执行全局代码会产生一个全局执行上下文。全局执行上下文只有一个,函数执行上下文会有多个。一个函数被调用了多少次,就会产生多少个函数执行上下文。
函数嵌套调用会形成执行上下文栈
var a = 1;
function f(){
console.log(1);
}
function f1(){
console.log(2)
f();
}
全局代码一执行,产生一个全局执行上下文,在最下面。
调用函数f1()产生一个f1函数执行上下文,这个执行上下文会放在全局执行上下文上面。
调用函数f()产生一个f执行上下文,这个执行上下文会放在f1函数执行上下文上面。
执行上下文栈:
最底层是全局执行上下文。
入栈:函数要执行了,函数的执行上下文入栈。
出栈:函数调用完成时,函数的执行上下文出栈。
作用域链
全局执行上下文包含全局变量和函数,局部执行上下文包含函数内部的变量,函数,arguments,父级函数的执行上下文。
在一个局部执行上下文中找一个数据,如果没有找到,就去父级函数的执行上下文中找,如果父里也没有,就去父级的父级的执行上下文中找,直到找到全局执行上下文,如果还找不到,就会报错。这个过程形成了一条链,就是作用域链。作用域链解释了为什么函数内部的变量在函数外无法访问。
闭包
如果一个函数A内部定义了函数B,并且函数B引用了A中定义的变量,则称函数B是一个闭包。一般我们在函数外部不能访问函数内部定义的变量,但是闭包提供了一种访问机制,在函数内部,把闭包返回,则可以实现在函数的外部区访问内部定义的变量。但这种方式的缺点是容易造成内存泄漏,因为闭包中的局部变量永远不会被回收,因为它们没人要了。