作用域链与上下文环境

var a=10;
function fn(){
	console.log(a)
}

function bar(f){
	var a=20;
	f();
}
bar(fn)

  函数每被调用一次,都会产生一个新的执行上下文环境。

函数在定义的时候(不是调用的时候),就已经确定了函数体内部自由变量的作用域。

首先,我们如何创建一个作用域呢,function()。除了全局作用域,只有函数才能创建作用域,也就是说for、if、while的{}是不能创建出作用域的。区别c++中的块作用域{}。

一个函数的作用域创建后,将贯穿他的始“{”,终“}”,作用域在函数创建时被存储,与函数共存亡。

这句话就应该着重理解贯穿2字了,若函数内部嵌套着多个函数,那么从最内层函数作用域依次往外就形成了作用域链

ps:需要我们理解作用域链的变量查找机制是由内往外的。先找自身作用域,再一次往外,若没有,则等同没有var时的声明(为全局添加了一个属性);

作用域链正是内部上下文所有变量对象(包括父变量对象)的列表。

一个作用域下可能包含若干个上下文环境。有可能从来没有过上下文环境(函数从来就没有被调用过);有可能有过,现在函数被调用完毕后,上下文环境被销毁了;有可能同时存在一个或多个(闭包)。

执行完第17行,fn(5)的返回值赋值给了f1。此时执行上下文环境又重新回到全局,但是fn(5)的上下文环境不能就此销毁,因为其中有闭包的引用

执行第18行,再次调用fn函数——fn(10)。产生fn(5)的上下文环境,并压栈,并设置为活动状态。但是此时fn(5)的上下文环境还在内存中——一个作用域下同时存在两个上下文环境。

原文地址:https://www.cnblogs.com/yiyi17/p/8629960.html