JavaScript作用域(二)

来源:互联网 发布:新闻联播视频制作软件 编辑:程序博客网 时间:2024/06/05 12:37

参考: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里面找,有,但是无定义,所以赋值scopelocal

                所以下次用时去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




阅读全文
0 0
原创粉丝点击