参考:JavaScript高级程序设计(第3版) 英文原版.pdf
一、建立execution context过程,
1、代码
var color = “blue”;//全局
function changeColor()
{ var anotherColor = “red”; //本地变量
function swapColors(){var tempColor = anotherColor; //子变量
anotherColor = color;
color = tempColor;
}
swapColors();
}
changeColor();
2、建立execution context后的图。
子函数可以访问父的数据,父的数据不能访问子的数据
执行过程:
1、首先建立global execution context,color变量,changeColor()函数 压入堆栈。
2、当浏览器执行到changeColor(),首先建立changeColor函数的execution context,
1》首先建立相应的函数参数,并赋值
2》查找这个函数里面的所有函数,函数名:指针
3》 查找这个函数里面的所有变量:undefined
当初始化完数据后,开始执行函数体代码
3、一行一行执行代码,
1> 执行 var anotherColor = “red”; 这一句,到当前execution
context 去找,发现没有赋值,则anotherColor :"red".
2> 执行 swapColors()这个函数,又需要建立对应execution context ,和前面一样,不重复。
这里当调用函数时,首先建立 execution context,也就是初始化函数里面的数据,这里和java建立对象时一样,当我们new 一个对象时,首先是去初始化类对象值,但是如果不赋值,也有一些默认值,如果赋值了,就等于写的值,然后对象才可以拿来用。
这里一样,要用函数,首先必须初始化里面的值,然后才开始使用,就是一些小规则不一样。
二、明明全局变量定义scope,为什么函数里不能用? console.log(scope); //undefined
例子1:
var scope="global"; function t(){ console.log(scope); //undefined var scope="local" console.log(scope); //"local" } t(); |
理由:javascript执行分两部分,1:建立阶段,也就是初始化阶段,2、执行阶段
第一:建立阶段,所有的变量赋值:undefined
第二:执行阶段,所有变量才真正赋值。
上面执行过程:
1、建立阶段,初始化函数里面用到的所有的变量值设置成undefined ,scope:undefined
2、执行阶段
1》第一条语句执行时查找execution context,找到scope=undefined ,
2》执行到 var scope="local" 时,首先去execution context里面找,有,但是无定义,所以赋值scope:local
所以下次用时去execution context,发现有值,就显示出来
例子2:js找变量对象的过程
var color = “blue”; function getColor(){ return color; } alert(getColor()); //”blue” |
第一:在getColor()函数本地execution context中,搜索getColor()的变量对象color
第二:没有找到,在全局execution context找变量对象color,是变量定义的地方,找到
结束。
注意:函数里定义一个同名的color,则不需要查找。
var color = “blue”; function getColor(){ var color = “red”; return color; } alert(getColor()); //”red” |
上面两个例子区别:第一个例子是函数里已经定义一个变量,所以初始值是undefine,
第二个例子根本无变量,所以取父execution context 找。
三、容易产生错误点,这里如何按照context 堆栈入对象法,也不会出错。但是刚从java转过来,有点奇怪。
1、lock-Level 作用域
下面在if里面的变量,java 中color出}就消失了,但是javascirpt存在。
理由:因为Javascript 会把所有的变量,不管存在什么地方,全部放到一个current execution context里面,所以都可以用,不知道什么时候删除这些变量?
if (true) { var color = “blue”; } alert(color); //”blue” |
for (var i=0; i < 10; i++){ doSomething(i); } alert(i); //10 |
for 里面有一个变量,所以也存最后一个值10.
上面两个,出了块,就不存在了,但是javascript仍然存在。
2、函数里的变量,sum 直接放入上文中(Context),当函数返回时,对象sum出Context堆栈。
对于闭包函数,有可能sum值还需要保存一段时间,
但是下面是普通函数,相加后返回一个总和,哪么函数外面不能访问函数里面的本地变量sum.。
function add(num1, num2) { var sum = num1 + num2; return sum; } var result = add(10, 20); //30 alert(sum); //causes an error since sum is not a valid variabl |