JavaScript 中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是 window 对象,所以所有的全局变量和函数都是作为 window 对象的属性和方法创建的。当某一个执行环境中所有代码执行完成后,该环境就被销毁,保存在其中的变量和函数也将被销毁,全局执行环境在关闭网页或浏览器时才被销毁。
当代码在一个环境中执行时,会创建变量对象的一个作用域链(保证对执行环境有权访问的变量和函数的有序访问),如果环境是函数,将其活动对象作为变量对象,活动对象最开始包含的变量只有一个,即 arguments 对象,arguments 对象在全局环境中是不存在的,作用域链中的下一个变量对象来自包含环境(或者称外部环境,即包含原执行环境的执行环境),再下一个变量对象则来自再下一个包含环境,一直延续到全局执行环境。
- var a = 1;
- function show(){
- alert(a);
- }
- show();
在这个例子中,函数 show() 的作用域链包含两个对象:一是它自己的变量对象,其中定义着 arguments 对象、二是全局环境中的变量对象。之所以能在函数内访问到变量 a,就是因为可以在作用域链中找到它。这里其实是有两步的搜索过程,首先搜索 show() 的变量对象,查找其中是否包含一个名为 a 的标识符;在没找到的情况下,搜索下一个变量对象(全局环境的变量对象),在那找到了名为 a 的标识符,因为找到了这个变量的变量对象,搜索也就结束了,过程如下图:
在 JavaScript 中没有块级作用域,如下:
- for(var i=0; i<5; i++){
- do(i);
- }
- alert(i); // 5
如果是在 Java、C 语言中,上面的 i 会在 for 语句执行完后就被销毁,但在 JavaScript 中,for 语句中的变量声明会将变量添加到当前的执行环境(if 语句也是),这里就是全局环境,所以即使是 for 循环执行完了,变量 i 也会存在循环外部的执行环境中。
在 JavaScript 中,使用 var 声明的变量会被添加到最接近的执行环境中,如果是在函数内声明的变量,最接近的环境就是函数的局部环境;如果初始化变量时没有使用 var 声明,该变量会被自动添加到全局环境中。如:
- function add(n1, n2){
- sum = n1 + n2;
- return sum;
- }
- var res = add(1, 2);
- alert(sum); // 3(因为sum没使用var声明,所以在函数外仍能访问到)
来源: http://www.bubuko.com/infodetail-1957078.html